Extrait du excellent manuel :
Donc :delete_all
prend soin des clés étrangères mais, comme aucun rappel n'est invoqué, il ne va qu'à un niveau. Donc ceci dans Company
:
has_many :projects, dependent: :delete_all
signifie qu'appeler #destroy
sur une entreprise supprimera directement les projects
associés de la base de données. Mais cela ne verra pas ceci :
has_many :tasks, dependent: :delete_all
que vous avez dans Project
et vous finissez par essayer de supprimer des projets qui sont toujours référencés dans tasks
comme l'indique le message d'erreur.
Vous pouvez basculer toutes vos associations vers dependent: :destroy
, cela extraira tout de la base de données avant de les détruire et des rappels seront appelés (ce qui chargera plus de choses hors de la base de données uniquement pour les détruire, ce qui chargera plus de choses hors de la base de données...). Le résultat final sera une grande activité dans la base de données, mais toutes les clés étrangères seront correctement suivies.
Alternativement, vous pouvez placer la logique dans la base de données où elle appartient habituellement en spécifiant on delete cascade
sur les contraintes de clé étrangère
:
Votre add_foreign_key
les appels ressembleraient à :
add_foreign_key "projects", "companies", on_delete: :cascade
add_foreign_key "tasks", "projects", on_delete: :cascade
add_foreign_key "task_times", "tasks", on_delete: :cascade
dans ce cas. Vous voudriez probablement laisser le dependent: :delete_all
s dans vos modèles pour vous rappeler ce qui se passe, ou vous pouvez vous laisser un commentaire.