Rails从两个查询的减法中删除返回的关系

时间:2014-10-29 16:11:27

标签: sql ruby-on-rails ruby database-relations

我有三个模特

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

类似这样的东西..任何其他的想法将非常感激,我希望找到一种方法来比较两个查询后得到一个关系对象,然后能够采取行动。

感谢您的帮助!

1 个答案:

答案 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