有效地过滤多对多

时间:2013-06-24 16:27:34

标签: sql ruby-on-rails activerecord many-to-many

在我写的应用程序中,我有可能属于任意数量的组的用户。通过相应的group_membership模型存在has_many关系。

我正在处理报告界面,并希望按群组进行过滤,因此我希望返回属于所有列出的群组的用户(即使他们属于其他其他群组)。

目前,我依次根据每个组的成员资格对这组用户进行反复过滤,以便在用户不是当前组的成员时过滤掉用户。

  @users = @account.users.joins(:groups).where("groups.id in (?)",all_groups).pluck('users.id') #All user IDs
  positions_users = @account.users.joins(:groups).where("groups.id in (?)",positions).pluck('users.id') unless positions.empty?
  departments_users = @account.users.joins(:groups).where("groups.id in (?)",departments).pluck('users.id') unless departments.empty?     
  locations_users = @account.users.joins(:groups).where("groups.id in (?)",locations).pluck('users.id') unless locations.empty?     
  miscellaneous_users = @account.users.joins(:groups).where("groups.id in (?)",miscellaneous).pluck('users.id') unless miscellaneous.empty? 


  @users = @users.select {|x| positions_users.include? x } unless positions_users.nil? || positions_users.empty?
  @users = @users.select {|x| departments_users.include? x } unless departments_users.nil? || departments_users.empty?
  @users = @users.select {|x| locations_users.include? x } unless locations_users.nil? || locations_users.empty? 
  @users = @users.select {|x| miscellaneous_users.include? x } unless miscellaneous_users.nil? || miscellaneous_users.empty?

有更有效的方法吗?

1 个答案:

答案 0 :(得分:1)

假设您有一个联接模型UserGroup,您可以添加以下范围:

class UserGroup
  scope :group_filter, lambda{|*groups|
    group_ids = groups.flatten.compact.uniq
    return self if group_ids.blank?
    where(:group_id => group_ids)
  }
end

现在你可以这样做:

filter = UserGroup.group_filter(positions, departments, locations, miscellaneous)
@users = @account.users.joins(:user_groups).merge(filter)

你做完了!