出于这个问题的目的,让我们假设我正在构建Stack Overflow。
我通过Posts
和Tags
的关联表获得了多对多关系,并且我想搜索包含多个标签的帖子。
我可以搜索包含单个标记的帖子,如下所示:
scope :has_tag, lambda { |tag| includes(:tags).where("lower(tags.name) = ?", tag.downcase) }
Post.has_tag("Python")
为了搜索多个标签,我尝试使用循环构建查询:
def self.has_tags(tags)
query = includes(:tags)
tags.each do |tag|
query = query.where("lower(tags.name) = ?", tag)
end
return query
end
这导致查询... WHERE (lower(tags.name) = 'tag1') AND (lower(tags.name) = 'tag2')
,它与任何内容都不匹配。
我也尝试使用.where('tags.name IN (?)', tags)
,但我认为匹配包含其中一个标记的帖子而不是包含所有标记的帖子。
现在我想也许我应该使用标签的ID,但这听起来好像会导致多次查询。这效率低吗?
... WHERE tag_id IN (SELECT id FROM tag WHERE name IN ('tag1','tag2'))
搜索多个标签的最佳方法是什么? (我更喜欢理解语法并手动操作而不是使用gem,因为我是Rails的新手。)
答案 0 :(得分:0)
我最终使用了以下内容:
scope :has_tags, lambda { |tags| includes(:tags)
.where("lower(tags.name) IN (?)", tags.collect { |tag| tag.downcase } )
.group('"posts"."id"')
.having('COUNT(DISTINCT "tags"."id") = ?', tags.count) }