From 71e1b6c97380f56834d26fbc7f47cd6ccf851c5c Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 23 Feb 2022 17:04:24 +0100 Subject: [PATCH 1/2] models: delete AdministrateursProcedure when destroying Administrateur By default, `has_and_belongs_to_many` properly deletes the record in the join table. However, as the association is declared manually with a `has_many / through`, it doesn't delete the joined record automatically. As we also lack a foreign-key contraint on the join table, that means a dangling record remains in the join table. To fix this, let's declare it a proper `has_and_belongs_to_many` association, which will let the join record be deleted automatically on destroy. --- app/models/administrateur.rb | 3 +-- spec/models/administrateur_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index ebd1e9470..7bdaa90fa 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -12,8 +12,7 @@ class Administrateur < ApplicationRecord include ActiveRecord::SecureToken has_and_belongs_to_many :instructeurs - has_many :administrateurs_procedures - has_many :procedures, through: :administrateurs_procedures + has_and_belongs_to_many :procedures has_many :services has_one :user, dependent: :nullify diff --git a/spec/models/administrateur_spec.rb b/spec/models/administrateur_spec.rb index 55e6c4d32..ce21fb67a 100644 --- a/spec/models/administrateur_spec.rb +++ b/spec/models/administrateur_spec.rb @@ -3,7 +3,7 @@ describe Administrateur, type: :model do describe 'associations' do it { is_expected.to have_and_belong_to_many(:instructeurs) } - it { is_expected.to have_many(:procedures) } + it { is_expected.to have_and_belong_to_many(:procedures) } end describe "#renew_api_token" do From 3fde7021e71f1d471e85d64b8efdfc2ca5aefd37 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 1 Mar 2022 07:47:39 +0000 Subject: [PATCH 2/2] db: add foreign key contraint to AdministrateursProcedure --- ...ur_foreign_key_to_administrateurs_procedure.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 db/migrate/20220301160753_add_administrateur_foreign_key_to_administrateurs_procedure.rb diff --git a/db/migrate/20220301160753_add_administrateur_foreign_key_to_administrateurs_procedure.rb b/db/migrate/20220301160753_add_administrateur_foreign_key_to_administrateurs_procedure.rb new file mode 100644 index 000000000..d8d0bbb0a --- /dev/null +++ b/db/migrate/20220301160753_add_administrateur_foreign_key_to_administrateurs_procedure.rb @@ -0,0 +1,15 @@ +class AddAdministrateurForeignKeyToAdministrateursProcedure < ActiveRecord::Migration[6.1] + def up + # Sanity check + say_with_time 'Removing AdministrateursProcedures where the associated Administrateur no longer exists ' do + deleted_administrateur_ids = AdministrateursProcedure.where.missing(:administrateur).pluck(:administrateur_id) + AdministrateursProcedure.where(administrateur_id: deleted_administrateur_ids).delete_all + end + + add_foreign_key :administrateurs_procedures, :administrateurs + end + + def down + remove_foreign_key :administrateurs_procedures, :administrateurs + end +end