我有三个模特
class Account
has_many :link_requests, :through => :suppliers
end
class Supplier
has_many :link_requests, :dependent => :destroy
end
class LinkRequest
belongs_to :supplier
belongs_to :account
end
我拥有它可以通过excel单独或批量输入供应商。
当单独删除供应商时,它将删除属于它的所有link_requests。但我们有一种方法可以通过SQL查询批量删除所有供应商。但是所有的link_requests都被遗忘了。我现在更新了查询,以便它处理这个异常,但现在我们最终得到了大量的死数据。
这是我能找出如何找到“死数据”的唯一方法。
LinkRequest.where(account_id: current_account)
将返回属于current_account的所有link_requests,已删除供应商和已包含现有供应商的link_requests为ActiveRecord::Relation
。
然后我可以致电:current_account.link_requests
,它会返回与现有供应商的所有link_requests,也会作为=> ActiveRecord::Relation
link_request
没有任何属性可以将现有供应商与已删除供应商的供应商分开。所以我不能只调用所有无效的,我知道它们有效的唯一方法是因为current_account通过其现有供应商获得其link_requests。
所以我最初的想法是从所有link_requests的总和中减去所有有效的那些,这样我将留下所有'无效请求',并在它们上调用destroy_all。
只有当我减去两个关系时,我得到一个数组。
LinkRequest.where(account_id: current_account).count
=> 10
current_account.link_requests.count
=> 4
(LinkRequest.where(acconut_id: current_account) - current_acconut.link_requests).count
=> 6 #these are all the invalid ones.
dead_links = (LinkRequest.where(acconut_id: current_account) - current_acconut.link_requests)
dead_links.class
=> Array
我无法在阵列上调用destroy_all,因为它与供应商db无关。我得到!! #<NoMethodError: undefined method 'destroy_all' for #<Array:0x007fdb59a67728>>
要将每个link_requests supplier_id与现有供应商数据库进行比较,然后删除不匹配的那些将是一项非常昂贵的操作,因为数据库拥有数亿种数据类型。所以我想在LinkRequests控制器上创建一个前置过滤器,当他运行索引操作时将删除它们当前帐户。
private
def clean_up_boogle_link_requests
@dead_requests = LinkRequest.where(account_id: current_account) - current_account.manual_boogle_link_requests
@dead_requests.delete_all if !dead_requests.empty?
end
类似这样的东西..任何其他的想法将非常感激,我希望找到一种方法来比较两个查询后得到一个关系对象,然后能够采取行动。
感谢您的帮助!
答案 0 :(得分:1)
我认为这会解决问题:
dead_link_ids = LinkRequest.where(acconut_id: current_account).pluck(:id) -
current_acconut.link_requests.pluck(:id)
LinkRequest.where(id: dead_link_ids).delete_all