匹配查询中的所有活动记录关系

时间:2013-07-29 09:33:08

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

我需要一个activerecord查询来匹配params数组中的所有项目。

让我们说用户has_many角色。每个角色都有一个名字。

当我通过['演员','制片人','歌手']时。我希望查询能够返回具有所有这三个或更多角色的用户。

但是下面的方法实现会返回至少有一个角色名称与传递的数组中的角色名称相匹配的用户

我当前的方法基于找到任何标签而不是“MATCH ALL”

来给出结果
class User < ActiveRecord::Base
    has_many :roles

    def self.filter_by_roles(roles)
        User.joins(:roles).includes(:roles).where(:roles => {:name => roles})
    end
end

请帮我解决这个问题。

在查询检查返回的结果对象是否包含所有角色之后,我不想做任何数组操作。这是因为我需要从此返回Active Record Relation对象。

提前致谢。

3 个答案:

答案 0 :(得分:3)

试试这个。

User.joins(:roles).includes(:roles).where(:roles => {:name => roles}).group('usermail').having("COUNT(DISTINCt role_id) = 3")

假设字段usermail用于识别用户。

答案 1 :(得分:0)

你可以试试这个:

def self.filter_by_roles(roles)
  scope = User.joins(:roles).includes(:roles)
  roles.each do |role|
   scope = scope.where(roles: {name: role})
  end
  scope
end

这是未经测试的,所以我不确定它是否有效。

答案 2 :(得分:0)

如果你传递了role_ids数组([1,2,3]),你可以像这样做:

def self.filter_by_roles(role_ids)  
  User.select{|user| (role_ids - user.role_ids).empty?}
end

但如果你按标题传递角色(['演员','制作人','歌手'])你需要这样的话:

def self.filter_by_roles(roles)
  role_ids = Role.find_all_by_title(roles).map(&:id)
  User.select{|user| (role_ids - user.role_ids).empty?}
end