PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PG ::ForeignKeyViolation :ERREUR :la mise à jour ou la suppression sur la table xxx viole la contrainte de clé étrangère

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.