我有一个典型的标签和任何对象关系:
class Tag < ActiveRecord::Base
attr_accessible :name
has_many :tagazations
has_many :projects, :through => :tagazations
end
class Tagazation < ActiveRecord::Base
belongs_to :project
belongs_to :tag
validates :tag_id, :uniqueness => { :scope => :project_id }
end
class Project < ActiveRecord::Base
has_many :tagazations
has_many :tags, :through => :tagazations
end
这里没什么特别的:每个项目都带有一个或多个标签。
该应用程序具有搜索功能:您可以选择某些标签,而我的应用程序应向您显示所有标有所有提及标签的项目。所以我得到了必要的tag_ids的数组,然后陷入了这样一个简单的问题
要在一个查询做到这一点,你会希望利用普通的双不存在SQL查询,基本上不求x的所有的Y。
在您的实例中,您可以执行以下操作:
class Project < ActiveRecord::Base
def with_tags(tag_ids)
where("NOT EXISTS (SELECT * FROM tags
WHERE NOT EXISTS (SELECT * FROM tagazations
WHERE tagazations.tag_id = tags.id
AND tagazations.project_id = projects.id)
AND tags.id IN (?))", tag_ids)
end
end
另外,您可以使用count,group和have,尽管我怀疑第一个版本会更快,但可以随时进行基准测试:
def with_tags(tag_ids)
joins(:tags).select('projects.*, count(tags.id) as tag_count')
.where(tags: { id: tag_ids }).group('projects.id')
.having('tag_count = ?', tag_ids.size)
end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句