Рейки: залежно =>: знищити VS: залежно =>: delete_all


192

У посібниках по рейках це описано так:

Об'єкти будуть додатково знищені, якщо вони пов’язані :dependent => :destroy, та видалені, якщо вони пов’язані:dependent => :delete_all

Правильно, круто. Але яка різниця між знищенням та видаленням? Я спробував і те, і інше, схоже, зробив те саме.

Відповіді:


200

Різниця полягає у зворотному дзвінку.

Це :delete_allзроблено безпосередньо у вашій програмі та видаляє SQL:

DELETE * FROM users where compagny_id = XXXX

З :destroyвами, є примірник всіх ваших дітей. Отже, якщо ви не можете його знищити або якщо у кожного є свої :dependent, його зворотні дзвінки можна викликати.


83
Ініціатива та виклик знищення на кожному з дитячих об'єктів будуть повільними, якщо у вас багато дітей (і n ^ 2, якщо у вас є онуки тощо). delete_all - це такий варіант рішення, як "запустити його з орбіти", де вам не байдуже / не маєте до / після знищення зворотних викликів на моделях.
Райан Бігг

131

У модельній асоціації Rails можна вказати :dependentпараметр, який може приймати одну з наступних трьох форм:

  • :destroy/:destroy_allПов'язані об'єкти знищуються поряд з цим об'єктом, викликаючи їх destroyметод
  • :delete/:delete_allВсі пов'язані об'єкти знищуються негайно, не викликаючи їх :destroyметод
  • :nullifyВстановлюються всі зовнішні ключі всіх пов'язаних об'єктів NULLбез виклику saveзворотних дзвінків

2
Дивіться api.rubyonrails.org/classes/ActiveRecord/Associations/… (шукайте "скасувати") для авторитетних rdocs.
мрм

21
Оскільки Rails 3.0 також можна вказати :restrict. Якщо встановлено значення: обмежити цей об'єкт не можна видалити, якщо він має будь-який асоційований об'єкт.
RocketR

17
немає :deleteчи :destroy_allваріантів за зовнішнім виглядом? : Залежний варіант очікує або: знищити,: delete_all,: анулювати або: обмежити (: видалити)
Майк Кемпбелл

2
@MikeCampbell, :deleteа :destroy_allваріантів не існує. Однак існують методи класів на моделях, які викликаються, deleteі destroy_allтому це може бути причиною плутанини.
Березівський

@MikeCampbell Вам не вистачає ще декількох варіантів, Дивіться: залежний варіант повинен бути одним із [: знищити,: delete_all,: звести нанівець,: restrict_with_error,: restrict_with_exception]
Pravin Mishra

30

Див. Знищення видаляє пов'язані з ним елементи, де delete_all може видалити декілька даних із самостільної таблиці якDELETE * FROM table where field = 'xyz'

: Залежні можливі варіанти:

Контролює, що відбувається з пов’язаними об’єктами, коли їх власник знищений. Зауважте, що вони реалізовані як зворотні дзвінки, а Rails виконує зворотні дзвінки в порядку. Тому інші подібні зворотні виклики можуть впливати на: залежну поведінку, а :dependentповедінка може впливати на інші зворотні виклики.

:destroy призводить до знищення всіх пов'язаних об'єктів.

:delete_all змушує видалити всі пов'язані об'єкти безпосередньо з бази даних (тому зворотні виклики не виконуватимуться).

:nullifyпризводить до встановлення стороннього ключа на NULL. Відклики викликів не виконуються.

:restrict_with_exception викликає виникнення винятку, якщо є якісь пов'язані записи.

:restrict_with_error викликає додавання помилки до власника, якщо є будь-які пов'язані об’єкти.

Якщо використовується з :throughопцією, асоціація в моделі приєднання повинна бути last_to, а записи, які видаляються, - це записи об'єднання, а не пов'язані з ними записи.


3

Насправді головна відмінність полягає в тому, що будь-які зворотні виклики не використовуються при :delete_allвикористанні. Але при використанні :destroyстек зворотних викликів ( :after_destroy, :after_commit...) буде запущений.

Отже, якщо у вас є touch:декларації у видалених моделях, то краще використовувати dependent: :delete_allскоріше "залежно:: знищити".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.