在我的数据库中,我在用户和角色之间建立了多对多的关系(HABTM)。我正在尝试为与特定秘书相关联的用户获取所有角色名称。
我设法将以下内容拼凑在一起:
class Secretary < ActiveRecord::Base
def getRoles
rolenames = Set.new
Role.all.map { |role| role.users.map { |user| rolenames << role.name if user.manager.secretary == self } }
rolenames.to_a
end
end
...哪个有效,但它似乎是一个精心设计的“where”语句应该产生相同的结果而不会如此多地访问数据库。
是否可以将上述内容转换为更“本机”的ActiveRecord查询?
答案 0 :(得分:1)
您没有提供足够的信息来清楚了解您的模型。从你提供的内容来看,我猜从秘书的角度看起来像这样:
Secretary
has_many :managers
Manager
has_namy :users
User
has_many :roles
从深层嵌套模型中检索记录时,根据id(外键)进行思考是有帮助的:Rails Nested SQL Queries
由于Rails会在where语句的哈希版本中自动将记录转换为id。
Role.where(:user_id => User.where(:manager_id => managers))
如果我对你的模型的假设是正确的,应该得到答案。
编辑: 好的,HABTM有点混乱了水。我们不能嵌套在哪里,但是我们仍然可以在不使用数据库的情况下进行一些映射。试试这个:
User.includes(:roles).where(manager_id: managers).flat_map(&:roles).map(&:name)
答案 1 :(得分:0)
您的模型似乎是这样的:
Role
has_many :users
User
belongs_to :role
has_one :manager, :class => 'User'
在这种情况下,只需将表格内部连接起来,即可获得您所追求的结果:
SELECT roles.* FROM roles
INNER JOIN users u ON u.role_id = roles.id
INNER JOIN users m ON m.id = u.id
此查询可以转换为以下内容:
Role.joins(:users => :manager)