Reputation: 47
For my Employee
class, I have the following self-joinig associations:
class Employee < ApplicationRecord
belongs_to :replaces_employee, class_name: "Employee", optional: true
has_one :replaced_by_employee,
class_name: 'Employee',
foreign_key: 'replaces_employee_id'
end
And my employees
DB table has the column replaces_employee_id
.
In my app, if an employee gets a new role, the following occurs:
<current record's>.replaces_employee
= cloned recordreplaces_employee_id
column with the cloned record ID.Yep, that magic was great and worked in my old Rails 4.2 app. Unfortunately this isn't working for my Rails 7.0 app. I've tried updating the belongs_to
association with an explicit foreign key to no avail. Please note for existing DB records that do have replaces_employee_id
populated, I have access to the associated ARs (i.e. Employee.find(1).replaces_employee
works).
Any ideas why this isn't working for Rails 7? Was there some configuration on the 4.2 side that I'm missing?
Upvotes: 0
Views: 74
Reputation: 30036
Besides that there is no update_attributes!
method in rails 7, everything seem to work:
# app/models/employee.rb
class Employee < ApplicationRecord
belongs_to :replaces_employee, class_name: "Employee", optional: true
has_one :replaced_by_employee, class_name: "Employee", foreign_key: "replaces_employee_id"
def replace
# how deep is deep clone? did you check for validation errors?
other = deep_clone
other.attributes = {name: "copy of #{name}"}
# call `save!` or `update!` to raise validation errors
# when you call `save` or `update` you need to check for `errors`
# employee.save
# employee.errors #=> ???
update!({name: "new name",
replaces_employee: other})
end
end
>> Employee.create!
=> #<Employee:0x00007eff8c5cc5a0 id: 1, name: nil, replaces_employee_id: nil>
>> Employee.first.replace
=> true
>> Employee.all
=>
[#<Employee:0x00007eff7e4e08c0 id: 1, name: "replaced name", replaces_employee_id: 2>,
#<Employee:0x00007eff7e4e0780 id: 2, name: "copy of ", replaces_employee_id: nil>]
>> 3.times { Employee.first.replace }
=> 3
# i just dont' know if that's how you expect this to work
>> Employee.all
=>
[#<Employee:0x00007eff8c11ce60 id: 1, name: "new name", replaces_employee_id: 5>,
#<Employee:0x00007eff8c11cd20 id: 2, name: "copy of ", replaces_employee_id: nil>,
#<Employee:0x00007eff8c11cbe0 id: 3, name: "copy of new name", replaces_employee_id: 2>,
#<Employee:0x00007eff8c11caa0 id: 4, name: "copy of new name", replaces_employee_id: 3>,
#<Employee:0x00007eff8c11c960 id: 5, name: "copy of new name", replaces_employee_id: 4>]
Upvotes: 0