2013-01-23 30 views
0

为了这个问题的目的,我们假设我正在构建Stack Overflow。包含多个标签的搜索范围

我有一个多对多的关系,通过关联表PostsTags,我想搜索包含多个标签的帖子。

我可以搜索包含这样一个标签的帖子:

def self.has_tags(tags) 
    query = includes(:tags) 
    tags.each do |tag| 
    query = query.where("lower(tags.name) = ?", tag) 
    end 
    return query 
end 

此:

scope :has_tag, lambda { |tag| includes(:tags).where("lower(tags.name) = ?", tag.downcase) } 

Post.has_tag("Python") 

用于搜索多个标签,我已经使用循环试图建立一个查询导致查询... 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')) 

什么是搜索多个标签的最佳方式?
(我更愿意理解语法和做手工,而不是使用的宝石,因为我是新来的Rails。)

回答

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