将Ruby映射语句转换为ActiveRecord查询?

时间:2013-08-28 17:57:45

标签: ruby-on-rails ruby ruby-on-rails-3 rails-activerecord

在我的数据库中,我在用户和角色之间建立了多对多的关系(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查询?

2 个答案:

答案 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)