如何在多态关联中获取特定类型的所有子项

bra*_*rad 5 activerecord ruby-on-rails polymorphic-associations ruby-on-rails-3 rails-activerecord

我写了一个有效的方法,但感觉不优雅。我想知道我是否错过了更好的方法。

我有一个像这样设置的多态关联;

class Employee < ActiveRecord::Base
  has_many :phones, as: :phoneable
end

class Client < ActiveRecord::Base
  has_many :phones, as: :phoneable
end

class Phone < ActiveRecord::Base
  belongs_to :phoneable, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)

我的手机表有标准phoneable_id:integerphoneable_type:string列。

我想要做的是为先前选定的一组员工获取所有电话,例如

employees = Employee.where role: 'peon'
Run Code Online (Sandbox Code Playgroud)

如果这是正常has_many关系,我会将我的电话查询写为;

Phone.where employee_id: employees
Run Code Online (Sandbox Code Playgroud)

为了在多态关系中做到这一点,我将查询写为;

Phone.where phoneable_type: 'employee', phoneable_id: employees
Run Code Online (Sandbox Code Playgroud)

这有效,但我觉得应该有比明确声明phoneable_type. 当出现一组员工时,Rails 是否有办法自动执行此操作,或者我是否过于简单?

Rai*_*Guy -1

您没有完全理解多态关联的重要性。如果您在模型中定义了它,则可以轻松获取记录,如下所示:

假设您的员工表中有一个“Peon”角色:

@employee = Employee.where(role: 'peon').first
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样获取记录:

 @employee.phones
Run Code Online (Sandbox Code Playgroud)

如果您想获取具有“peon”角色的员工的所有电话,您可以这样做:

@employees = Employee.where(role: 'peon')   

@peon_phones = @employees.map{|x| x.phones}
Run Code Online (Sandbox Code Playgroud)

客户的情况也一样:

@client = Client.first

@client.phones
Run Code Online (Sandbox Code Playgroud)

正如您想象的那样简单。希望它会有所帮助。谢谢

  • 是的,除了使用这样的地图会导致大量的数据库请求并且可能非常慢。我一直在寻找仅数据库的解决方案。 (3认同)