ActiveRecord: Nullify foreign key after deleting a child in self-joins
Asked Answered
D

2

9

I have a self-join for my model in ActiveRecord, as follows:

class Employee < ActiveRecord::Base
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id"

  belongs_to :manager, class_name: "Employee"
end 

If I delete a Manager row, I expect 'manager_id' foreign key values for all employees that were under that Manager to be set to NULL. Is this something that is handles implicitly by ActiveRecord, or is it something that needs to be defined somewhere.

Distil answered 12/8, 2015 at 18:44 Comment(0)
P
12

You want to add dependent: :nullify to your has_many association.

class Employee…
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id",
                          dependent: :nullify
end

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

Parakeet answered 12/8, 2015 at 18:48 Comment(3)
Hum. True. That's what OP asked.Eckhardt
I am not sure that is what I am looking for. I am new to Ruby, so I might be wrong. But basically, I have an Employee model with a self-join. I want the foreign-key manager_id to be set to null for employees when the corresponding manager (also an entity of the employee table) is deleted. What you seem to be suggesting is a different Manager class itselfDistil
@NeelVasa Oops! My bad. I missed that part. Same idea though. Add the dependent: :nullify to your has_many :subordinates line. I'll update the code.Parakeet
A
4

Ideally you should have the trigger be set in your database and not rely on Active Record to perform updates.


If you are just creating the table, you can:

create_table :employees do |t|
  t.references :manager, foreign_key: {to_table: :employees, on_delete: :nullify}
  # ...
end

Alternatively, if the table already exists and you are just adding the reference:

add_reference :employees,
              :manager,
              foreign_key: {to_table: :employees, on_delete: :nullify}
Altdorf answered 1/6, 2018 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.