Rails:Has_many通过关联 - 使用AND条件查找,而不是OR条件

时间:2011-04-29 18:11:00

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

我的ActiveRecord模型中有以下查询方法:

def self.tagged_with( string )
    array = string.split(',').map{ |s| s.lstrip }
    select('distinct photos.*').joins(:tags).where('tags.name' => array )
end

因此,它会查找所有带有标记的记录,这些标记取自逗号分隔列表并转换为数组。

目前,这会将记录与任何匹配的标记进行匹配 - 如何在匹配所有标记的位置使其生效。

IE:如果我现在输入:“蓝色,红色”,那么我将获得所有用蓝色或红色标记的记录。

我希望匹配所有用蓝色和红色标记的记录。

建议?

- 编辑 -

我的模特是这样的:

class Photo < ActiveRecord::Base
  ...
  has_many :taggings, :dependent => :destroy
  has_many :tags, :through => :taggings
  ...
  def self.tagged_with( string )
    array = string.split(',').map{ |s| s.lstrip }
    select('distinct photos.*').joins(:tags).where('tags.name' => array )
  end
  ...
end

class Tag < ActiveRecord::Base
  has_many :taggings, :dependent => :destroy
  has_many :photos, :through => :taggings
end

class Tagging < ActiveRecord::Base
  belongs_to :photo
  belongs_to :tag
end

标签有两个属性:ID和Name(字符串)。

3 个答案:

答案 0 :(得分:5)

这应该有效:

def self.tagged_with( string )
  array = string.split(',').map{ |s| s.lstrip }
  select('distinct photos.*').
    joins(:tags).
    where('tags.name' => array).
    group("photos.id").
    having("count(*) = #{array.size}")
end

以上将匹配至少标记为红色和蓝色的照片。这意味着如果照片有红色,蓝色绿色标签,那么这张照片也会匹配。

答案 1 :(得分:1)

您可以将select语句更改为以下内容:

select('distinct photos.*').joins(:tags).where('tags.name = ?',  array.join(' OR '))

这将在where子句中正确创建OR字符串。

伊恩。

答案 2 :(得分:1)

LOL解决方案不是一个简单的任务 - 我从SQL的角度考虑它并且它是UGLY。我想其他人必须尝试这个,所以我做了一些搜索,发现这篇文章可以帮助你:

HABTM finds with "AND" joins, NOT "OR"