搜索范围包含多个标记

时间:2013-01-23 02:40:11

标签: sql ruby-on-rails rails-activerecord

出于这个问题的目的,让我们假设我正在构建Stack Overflow。

我通过PostsTags的关联表获得了多对多关系,并且我想搜索包含多个标签的帖子。

我可以搜索包含单个标记的帖子,如下所示:

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的新手。)

1 个答案:

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