sql >> Base de Datos >  >> RDS >> PostgreSQL

PG::ForeignKeyViolation:ERROR:actualizar o eliminar en la tabla xxx viola la restricción de clave externa

Del buen manual :

Entonces :delete_all se encarga de las claves foráneas pero, dado que no se invocan devoluciones de llamada, solo tiene un nivel de profundidad. Entonces esto en Company :

has_many :projects, dependent: :delete_all

significa que llamar a #destroy en una empresa eliminará directamente los projects asociados de la base de datos Pero eso no verá esto:

has_many :tasks, dependent: :delete_all

que tienes en Project y termina intentando eliminar proyectos a los que todavía se hace referencia en tasks como indica el mensaje de error.

Puede cambiar todas sus asociaciones a dependent: :destroy , esto sacará todo de la base de datos antes de destruirlos y se llamará a las devoluciones de llamada (lo que cargará más cosas de la base de datos solo para destruirlas, lo que cargará más cosas de la base de datos...). El resultado final será mucha actividad en la base de datos, pero todas las claves foráneas se seguirán correctamente.

Alternativamente, puede colocar la lógica dentro de la base de datos donde normalmente pertenece especificando on delete cascade sobre las restricciones de clave externa :

Su add_foreign_key las llamadas se verían así:

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

en este caso. Probablemente quieras dejar el dependent: :delete_all s en sus modelos como un recordatorio de lo que está pasando, o puede dejarse un comentario.