如何通过尚未保存的父关联访问ActiveRecord祖父母关联?

Rya*_*dge 6 ruby activerecord ruby-on-rails

我有一种情况,我希望在保存父对象之前访问相关的祖父母.我可以想到几个黑客,但我正在寻找一种干净的方法来实现这一目标.以下代码作为我的问题的说明:

class Company < ActiveRecord::Base
  has_many :departments
  has_many :custom_fields
  has_many :employees, :through => :departments
end
class Department < ActiveRecord::Base
  belongs_to :company
  has_many :employees
end
class Employee < ActiveRecord::Base
  belongs_to :department
  delegate :company, :to => :department
end

company = Company.find(1)           # => <Company id: 1>
dept = company.departments.build    # => <Department id: nil, company_id: 1>
empl = dept.employees.build         # => <Employee id: nil, department_id: nil>

empl.company   # => Employee#company delegated to department.company, but department is nil
Run Code Online (Sandbox Code Playgroud)

我正在使用Rails 3.2.15.我理解这里发生了什么,我理解为什么empl.department_id是零; 虽然我希望Rails在调用save之前直接引用预期关联,这样最后一行可以通过未保存的部门对象委派.有干净的工作吗?

更新:我在Rails 4中也试过这个,这是一个控制台会话:

2.0.0-p247 :001 > company = Company.find(1)
  Company Load (1.5ms)  SELECT "companies".* FROM "companies" WHERE "companies"."id" = ? LIMIT 1  [["id", 1]]
 => #<Company id: 1, name: nil, created_at: "2013-10-24 03:36:11", updated_at: "2013-10-24 03:36:11"> 
2.0.0-p247 :002 > dept = company.departments.build
 => #<Department id: nil, name: nil, company_id: 1, created_at: nil, updated_at: nil> 
2.0.0-p247 :003 > empl = dept.employees.build
 => #<Employee id: nil, name: nil, department_id: nil, created_at: nil, updated_at: nil> 
2.0.0-p247 :004 > empl.company
RuntimeError: Employee#company delegated to department.company, but department is nil: #<Employee id: nil, name: nil, department_id: nil, created_at: nil, updated_at: nil>
2.0.0-p247 :005 > empl.department
 => nil 
Run Code Online (Sandbox Code Playgroud)

更新2:这是github上测试项目.

kri*_*lim 5

请查看和的:inverse_of选项.在不同情况下构建和获取关联记录时,此选项将处理双向分配.belongs_tohas_many

双向协会ActiveRecord::Associations::ClassMethods在文档:

通过指定:inverse_of关联选项,您可以告诉Active Record有关反向关系的信息,它将优化对象加载.