2

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

假设用户 has_many 角色。每个角色都有一个名字。

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

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

我目前的方法是根据找到任何标签而不是“匹配所有”来给出结果

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 对象。

提前致谢。

4

3 回答 3

4

尝试这个。

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

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

于 2013-07-29T11:56:48.057 回答
0

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

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

但是,如果您按标题传递角色(['actor', 'producer', 'singer']),您需要像这样:

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
于 2013-07-29T11:27:16.513 回答
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

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

于 2013-07-29T10:25:07.103 回答