2013-08-28 33 views
1

在我的数据库中,用户和角色之间有多对多的关系(HABTM)。我正在尝试为与特定秘书相关联的用户获取所有角色名称。将Ruby映射语句转换为ActiveRecord查询?

我好不容易才凑齐了以下内容:

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 

...它的工作原理,但它似乎是一个正确的制作“其中”语句应该产生相同的结果而无需访问数据库这么多。

是否有可能将上述转换为更“本地”的ActiveRecord查询?

回答

1

您还没有给予足够的信息,以获得清晰的你的模型的图片。从你没有提供我猜它看起来像这样从视书记的观点:

Secretary 
has_many :managers 

Manager 
has_namy :users 

User 
has_many :roles 

当检索从深度嵌套模式记录它有助于觉得在id的(外键)方面: Rails Nested SQL Queries

由于滑轨的哈希版本里面会自动转换成记录的ID为您where语句..

Role.where(:user_id => User.where(:manager_id => managers)) 

应该得到你的答案,如果我对你的模型假设是正确的。

编辑: 好的,HABTM混浊了一点水。我们不能在任何地方嵌套,但我们仍然可以在不影响数据库的情况下做一些测绘。试试这个:

User.includes(:roles).where(manager_id: managers).flat_map(&:roles).map(&:name) 
+0

正如问题所述,用户和角色之间的关系是一个HABTM关系(has_and_belongs_to_many,带有一个连接表)。管理人员确实拥有该系统的许多用户,而秘书的确有很多管理人员。所以查询应该返回给定秘书下给定经理下的所有用户的角色集合。这是否澄清了这个问题? – user456584

+0

这应该工作。你试过了吗? – seph

+0

内部查询有效,但外部'Role.where(:user_id => ...)'查询似乎没有返回任何内容。我也尝试过'Role.include(:users).where(:user_id => ...)'类似的结果。 – user456584

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) 
+0

在这种情况下,经理和秘书都不是用户。 – user456584