PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PG::ForeignKeyViolation:ERRORE:l'aggiornamento o l'eliminazione sulla tabella xxx viola il vincolo della chiave esterna

Dal ottimo manuale :

Quindi :delete_all si prende cura delle chiavi esterne ma, poiché non vengono invocate callback, va solo un livello in profondità. Quindi questo in Company :

has_many :projects, dependent: :delete_all

significa che chiamare #destroy su un'azienda cancellerà direttamente i projects associati dalla banca dati. Ma questo non vedrà questo:

has_many :tasks, dependent: :delete_all

che hai in Project e finisci per eliminare i progetti che sono ancora referenziati in tasks come indica il messaggio di errore.

Puoi cambiare tutte le tue associazioni in dependent: :destroy , questo estrarrà tutto dal database prima di distruggerli e verranno chiamati i callback (che caricheranno più cose dal database solo per distruggerli che caricherà più cose dal database...). Il risultato finale sarà molta attività di database ma tutte le chiavi esterne verranno seguite correttamente.

In alternativa, puoi inserire la logica all'interno del database a cui appartiene di solito specificando on delete cascade sui vincoli di chiave esterna :

Il tuo add_foreign_key le chiamate sarebbero simili a:

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

in questo caso. Probabilmente vorrai lasciare il dependent: :delete_all s nei tuoi modelli come promemoria su cosa sta succedendo, oppure potresti lasciare un commento a te stesso.