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.