【问题标题】:Query on two HABTM models (Rails3)查询两个 HABTM 模型 (Rails3)
【发布时间】:2011-07-19 07:39:03
【问题描述】:

我有两个模型,客户端和具有 HABTM 关联的项目。我想找到选择所有客户的最快方法,这些客户有几个(多个)项目(或一定数量的项目)。

class Client < ActiveRecord::Base
  has_and_belongs_to_many :items
end

class Item < ActiveRecord::Base
  has_and_belongs_to_many :clients
end

下面的查询从列表中获取具有任何一项的客户端:

required_item_ids = Item.where(:kind => :book).collect(&:id)
Client.join(:items).where(:items => {:id => required_item_ids})

但需要的是拥有几个或所有必需项目的客户列表。

我相信这是一个简单的问题,因为我是 Rails 的新手,但我在这里和其他一些地方查看了所有类似的问题,但没有找到答案。

【问题讨论】:

  • 我认为你不能直接用 AR 做到这一点。您可能必须编写自己的 SQL(对于每个客户端,选择所有项目,然后检查 required_items 是否包含在所选项目中;如果是,则返回客户端)

标签: ruby-on-rails ruby-on-rails-3 activerecord associations has-and-belongs-to-many


【解决方案1】:

如果这是一次性的工作,那么您可以通过循环访问 Ruby 中的所有客户端来获取此列表。比如:

clients_with_more_than_one_book_items = []
book_items = Item.where(:kind => :book)

Client.find_each do |client|
  books_count = 0
  client.items.each do |item|
     if book_items.include?(item)
        books_count += 1
     end
  end

  clients_with_more_than_one_book_items << client if books_count > 1
end

但是,如果您有很多客户端和项目,这可能需要一段时间才能运行,因此如果这是您经常运行的查询,最好将 books_count 属性添加到客户端模型, 并添加代码(在模型的回调中)作为一种计数器缓存保持更新。

【讨论】:

  • 谢谢你,弗兰基。也想到了这一点,但这是一个昂贵的查询,我正在寻找一个更快的解决方案。如果没有其他方法,使用计数器缓存似乎没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多