legendary_rob
legendary_rob

Reputation: 13002

Rails 4 dependant destroy through nested relationships

I am trying to run a script to delete a whole bunch of students from our system, I am relying on the rails dependent: :destroy convention to make sure I clean up all data that's is related to those students.

I am pretty new to this system but this is how they structured the has_many relationships within the student_application model which belongs to a student.

student.rb student model

has_many :applications, class_name: "StudentApplication", dependent: :destroy
has_many :season_classes, through: :applications
has_many :payments, foreign_key: "student_id", dependent: :destroy

student_application.rb student_application model

belongs_to :student, touch: true
has_many :user_application_statuses, -> { order(id: :asc) }, dependent: :destroy
has_many :user_application_tasks, through: :user_application_statuses
has_many :file_upload_tasks, through: :user_application_statuses, class_name: "Tasks::FileUploadTask", source: :user_application_tasks
has_many :payment_tasks, through: :user_application_statuses, class_name: "Tasks::PaymentTask", source: :user_application_tasks
has_many :payments, through: :payment_tasks

user_application_status.rb user_applicaton_status model

belongs_to :application_status

# Student links
belongs_to :student_application
has_one :student, through: :student_application

payment.rb payment model

belongs_to :student
has_one :payment_task, class_name: "Tasks::PaymentTask"
has_many :transactions

When I delete a user I am getting this error

PG::ForeignKeyViolation: ERROR:  update or delete on table "student_applications" violates foreign key constraint "payments_student_application_id_fkey" on table "payments"
DETAIL:  Key (id)=(24747) is still referenced from table "payments".
: DELETE FROM "student_applications" WHERE "student_applications"."id" = $1
  (0.3ms)  ROLLBACK
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  update or delete on table "student_applications" violates foreign key constraint "payments_student_application_id_fkey" on table "payments"
DETAIL:  Key (id)=(24747) is still referenced from table "payments".
: DELETE FROM "student_applications" WHERE "student_applications"."id" = $1

At first I thought that there was an object at a deeper relationship level that was being left out. But as far as I can tell from looking at the tables and the source code there is no payments_student_application_id_fkey reference anywhere in the code, but i have found this in the structure.sql file

 --
 -- Name: payments_student_application_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
 --

 ALTER TABLE ONLY payments
     ADD CONSTRAINT payments_student_application_id_fkey FOREIGN KEY (student_application_id) REFERENCES student_applications(id);

We are using Rails 4.1.14.1 and Ruby 2.1.6 and Postgres for the db. Any ideas as to what could be causing this issue?

Upvotes: 0

Views: 1052

Answers (1)

x6iae
x6iae

Reputation: 4164

From What I can see...

# in pseudocodes
user has_one or has_many student_application dependent destroy
student_application belongs to a user
student_application has_many payments

Therefore deleting a user causes the associated student_application to get deleted as well... but the student_application's id is being referenced from the payments table, therefore causing the error.

Two ready solutions I can see:

1) Set a dependent: :destroy on the student_application model for payments ( or payment_tasks ) as well. This will ensure that the payments also gets deleted as well.

However, if you don't want this to be the case... then option 2:

2) Set a dependent: :nullify on the student_application model for payments. This will ensure that the ``student_application_idcolumn on the associatedpaymentsobject to the deletedstudent_application` is set to null, preventing the above error.

:dependent Controls what happens to the associated objects when the associated parent is destroyed. More options for dependent can be found here.

Upvotes: 2

Related Questions