От изящно ръководство :
Така че :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
е във вашите модели като напомняне какво се случва или можете да оставите коментар.