'FOREIGN KEY ON DELETE SET NULL in rails
I'm working with two models in rails
class Student < ApplicationRecord
belongs_to :school
has_many :lessons
end
and
class Lesson < ApplicationRecord
belongs_to :student, optional: true
end
I was really hoping this would result in what Oracle does with FOREIGN KEY ON DELETE SET NULL
after I do rails db:migrate:reset I get a generated db/schema.rb with the line
add_foreign_key "lessons", "students"
Which is not what I was expecting given my models, so I modified it by hand to
add_foreign_key "lessons", "students", on_delete: :nullify
No matter what I do, I get a foreign key violation every time I try to delete a student who has lessons.
Why doesn't the schema.rb reflect the models in the first place?
Why don't the tables reflect the changes I made to schema.rb by hand?
How do I delete a student without deleting all the lessons?
Solution 1:[1]
Why doesn't the schema.rb reflect the models in the first place?
because rails db:migrate:reset uses the files in db/migrate to generate the database, not the app/models files
either figure out the correct 'rails generate' command to create the correct
db/migrate/timestamp_do_this_or_that.rb
file or pick an existing (later) db/migrate/timestamp_do_this_or_that.rb file and add this line between 'def change' and 'end':
add_foreign_key "lessons", "students", on_delete: :nullify
rails db:migrate:reset
rails db:seed
and any student can be deleted even if he/she has lessons and where their id used to be in the lesson table is now 'nil'
Why don't the tables reflect the changes I made to schema.rb by hand?
I can't say for sure, but perhaps the autogenerated schema.rb file is just for reference. It does say in the comments at the top of the file:
# Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition
Solution 2:[2]
if you don't want to reset the whole db you can also specify it in the model with dependent option
class Student < ApplicationRecord
belongs_to :school
has_many :lessons, dependent: :nullify
end
class Lesson < ApplicationRecord
belongs_to :student, optional: true
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | elMatador |