复杂Rails使用ActiveRecord查询多对多关系

时间:2015-06-12 21:03:24

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

我有以下型号

class Element
  has_many :tags, through: :tags_elements
end

class Tag
  has_many :elements, through: :tags_elements
end

我需要:与变量上定义的所有标签相关的元素。 即所有带标签的元素:[" gt40"," car"]

我尝试了以下内容:

class Element   
  scope :search_tags, lambda { |df|
    joins(tags_elements: :tag)
    .where('tags.name IN (?) ', df)
    .distinct('id')
  }

所以我可以做到

tag_list = ["gt40","car"]
Element.search_tags(tag_list)

但它返回包含任何标签的外部元素。但是我需要与ALL标签相关的元素。

任何帮助?

2 个答案:

答案 0 :(得分:1)

我不认为这是最佳解决方案......但你可以做到

而不是范围

def self.search_tags(tag_list)
  elements_with_any_tags = self.joins(:tags).where(tags: {name: tag_list}).uniq

  elements_with_any_tags.select{|element| (tag_list - element.tags.map(&:name)).empty?}
end

这将返回包含所有选定标签的元素数组。

答案 1 :(得分:1)

你应该能够:

Element.
  joins(:tags).
  where(:tags => {:name => ["gt40","car"]}).
  group(:id).
  having("count(*) = ?", ["gt40","car"].size)

换句话说,确保连接标签的数量等于数组中标签的数量。