支持,我有两个模型项目和类别分类,在许多一对多的关系ActiveRecord的发现包含至少一个项目
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
现在我想筛选出其中至少包含一个项目类别,最好的办法是什么?
支持,我有两个模型项目和类别分类,在许多一对多的关系ActiveRecord的发现包含至少一个项目
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
现在我想筛选出其中至少包含一个项目类别,最好的办法是什么?
请注意,其他人answererd是不是表演!
最高效的解决方案:
更好的工作与counter_cache并保存items_count模型!
scope :with_items, where("items_count > 0")
has_and_belongs_to_many :categories, :after_add=>:update_count, :after_remove=>:update_count
def update_count(category)
category.items_count = category.items.count
category.save
end
正常 “belongs_to的” 关系你只写
belongs_to :parent, :counter_cache=>true
,并在parent_model你有一个场items_count(项目是多元化的的has_many类名)
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
在has_and_belongs_to_many关系中,你必须按照你自己的方式写出它
Category.joins(:items)
更多细节在这里:http://guides.rubyonrails.org/active_record_querying.html#joining-tables
scope :has_item, where("#{table_name}.id IN (SELECT categories_items.category_id FROM categories_items")
这将返回其具有在连接表项的所有类别,因为表面上,一类不应该有一个入口那里,如果它没有一个物品。您可以将AND categories_items.item_id IS NOT NULL
添加到子选择条件中以确保。
如果您不知道,table_name
是返回调用它的ActiveRecord类的表名称的方法。在这种情况下,它将是"categories"
。
我想回应@ Delba的回答,并对其进行扩展,因为它是正确的 - 如果你的索引设置正确,@huan儿子建议的count列是完全不必要的。
我想补充一点,你可能想使用.uniq,因为它是一个多到许多你只是想不同的类别回来:
Category.joins(:items).uniq
使用联接查询将让你更轻松地工作将项目数量也考虑在内,给予更多的灵活性。例如,你可能不希望清点货物,其中启用=假:
Category.joins(:items).where(:items => { :enabled => true }).uniq
这将生成的SQL语句,使用内部联接这是非常快:
SELECT `categories`.* FROM `categories` INNER JOIN `categories_items` ON `categories_items`.`category_id` = `categories`.`id` INNER JOIN `items` ON `items`.`id` = `categories_items`.`item_id` WHERE `items`.`enabled` = 1
祝你好运, 斯图
它可能性能较差,但它依赖于RDBMS来保持一致性(它们专门为此设计的)。根据Rails如何执行after_add回调(例如,它是否在事务中),最终可能导致计数不一致。 – ahlatimer
您可以为这些案例编写测试,并将事务包装在其中。那不是问题。但事实上:你有2500个类别,里面都有10-500篇文章。你知道查询有多大吗? :) –
你知道查询有多大吗?内部加入速度非常快,即使对于数千条记录,您的保存也很少。并且您正在假设类别和项目被插入/添加的次数与它们被选择的次数之间的关系。所以它*可能不会更高性能 – Stu