От изящно ръководство :
Така че :delete_all се грижи за външни ключове, но тъй като не се извикват обратни извиквания, той отива само на едно ниво на дълбочина. Това е във Company :
has_many :projects, dependent: :delete_all
означава, че извикването на #destroy на компания директно ще изтрие свързаните projects от базата данни. Но това няма да види това:
has_many :tasks, dependent: :delete_all
които имате в Project и в крайна сметка се опитвате да изтриете проекти, които все още се споменават в tasks както показва съобщението за грешка.
Можете да превключите всичките си асоциации на dependent: :destroy , това ще извади всичко от базата данни, преди да ги унищожи и ще бъдат извикани обратни извиквания (което ще зареди повече неща от базата данни само за да ги унищожи, което ще зареди повече неща от базата данни...). Крайният резултат ще бъде много активност в базата данни, но всички външни ключове ще бъдат правилно следвани.
Като алтернатива можете да поставите логиката в базата данни, където обикновено й е мястото, като посочите on delete cascade върху ограниченията на външния ключ
:
Вашият add_foreign_key обажданията ще изглеждат така:
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
в такъв случай. Вероятно бихте искали да оставите dependent: :delete_all е във вашите модели като напомняне какво се случва или можете да оставите коментар.