2

我希望能够选择具有多个角色的用户:

User < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

Role < ActiveRecord::Base
  has_and_belongs_to_many :users
end

我知道如何选择具有两个角色之一的用户:

User.joins(:roles).where(roles: { name: [:admin, :manager] })

但是如何找到至少拥有 :admin AND :manager 角色的所有用户?

4

4 回答 4

1

这是一个有效的解决方案:

User.select("DISTINCT users.*").
  joins("JOIN users_roles a ON a.user_id = users.id").
  joins("JOIN roles b ON b.id = a.role_id").
  joins("JOIN users_roles c ON c.user_id = users.id").
  joins("JOIN roles d ON d.id = c.role_id").
  where("b.name = ? and d.name = ? ", :admin, :manager)
于 2012-09-11T00:42:41.637 回答
1

这将起作用:

users = User.joins(:roles)
users.where("roles.name" => "admin") & users.where("roles.name" => "manager")

请注意,这会产生两个 SQL 负载查询,我认为这对于这种类型的搜索可能是不可避免的。(您的替代解决方案也进行两个 SQL 查询。)另请注意,它返回一个数组而不是一个活动记录关系,这可能不是您想要的。

于 2012-09-11T01:41:06.857 回答
0

如果将关联设置为has_many :through,则可以按用户计算唯一角色:

class User < ActiveRecord::Base
  has_many :user_roles
  has_many :roles, :through => :user_roles
end

# Note: add an id column on the join table
class UserRole < ActiveRecord::Base
  belongs_to :user
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :user_roles
  has_many :users, :through => :user_roles
end


User.joins(:user_roles => :role).
  select("users.*, COUNT(DISTINCT user_roles.id) as user_role_count").
  where("roles.name IN ('Admin','Manager')").
  group("users.id").
  having("user_role_count = 2")
于 2012-09-11T02:51:56.593 回答
0

这有效,但感觉不对:

Role.where(name: :admin).first.users.joins(:roles).where(roles: { name: :manager } )
于 2012-09-11T00:23:40.433 回答