Mam sytuację, w której chciałbym uzyskać dostęp do powiązanego dziadka przed zapisaniem obiektu nadrzędnego. Mogę wymyślić kilka hacków, ale szukam czystej drogi, aby to osiągnąć. Poniższy kod ilustruje mój problem:Jak uzyskać dostęp do powiązania między dziadkami ActiveRecord za pośrednictwem powiązania nadrzędnego, które nie zostało jeszcze zapisane?
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
Używam Rails 3.2.15. Rozumiem, co się tutaj dzieje i rozumiem, dlaczego empl.department_id ma wartość nil; Chciałem jednak, aby Railsy odwoływały się do przyszłego skojarzenia przed wywołaniem zapisu, tak aby ostatnia linia mogła być delegowana przez niezapisany obiekt działu. Czy jest czysta praca?
UPDATE: Próbowałem to w Rails 4, jak również, o to sesja konsoli:
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
UPDATE 2: Oto test project on github.
Jak bardzo dziwne. Muszę to wypróbować później. Wczoraj wieczorem działało dość wesoło. Sprawdź, czy 'empl.association (: department) == Employee.new.association (: department)' ... – struthersneil
Wynikiem tego wyrażenia jest "false". Widzę, że istnieje zmienna instancji '@ target' na skojarzeniu, która zawsze wydaje się być' nil' (nawet dla zapisanych rekordów). Nie wiem, jaki powinien być cel "@ target", ale miałoby to dla mnie sens, gdyby zawierało ono odnośnik, którego pragnę. –