Więc :delete_all
zajmuje się kluczami obcymi, ale ponieważ nie są wywoływane żadne wywołania zwrotne, sięga tylko do jednego poziomu. Więc to w Company
:
has_many :projects, dependent: :delete_all
oznacza, że wywołanie #destroy
w firmie spowoduje bezpośrednie usunięcie powiązanych projects
z bazy danych. Ale to nie spowoduje zobaczenia tego:
has_many :tasks, dependent: :delete_all
które masz w Project
i w końcu próbujesz usunąć projekty, do których nadal istnieją odniesienia w tasks
jak wskazuje komunikat o błędzie.
Możesz przełączyć wszystkie swoje asocjacje na dependent: :destroy
, spowoduje to wyciągnięcie wszystkiego z bazy danych przed ich zniszczeniem i wywołanie wywołań zwrotnych (które załadują więcej rzeczy z bazy danych tylko po to, aby je zniszczyć, co spowoduje załadowanie większej liczby rzeczy z bazy danych...). Efektem końcowym będzie duża aktywność bazy danych, ale wszystkie klucze obce będą prawidłowo przestrzegane.
Alternatywnie możesz umieścić logikę w bazie danych, gdzie zwykle należy, określając on delete cascade
na ograniczeniach kluczy obcych
:
Twój add_foreign_key
połączenia wyglądałyby tak:
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
w tym przypadku. Prawdopodobnie chciałbyś zostawić dependent: :delete_all
s w swoich modelach jako przypomnienie o tym, co się dzieje, lub możesz zostawić sobie komentarz.