Rails: depend =>: destroy VS: depend =>: delete_all
В рельсовых направляющих он описывается следующим образом:
Объекты будут дополнительно уничтожены, если они связаны с :dependent => :destroy
и удалены, если они связаны с :dependent => :delete_all
Верно, круто. Но какая разница между уничтожением и удалением?
Я пробовал оба, и похоже, что он делает то же самое.
Ответы
Ответ 1
Разница заключается в обратном вызове.
:delete_all
выполняется непосредственно в вашем приложении и удаляется SQL:
DELETE * FROM users where compagny_id = XXXX
С помощью :destroy
создается экземпляр всех ваших детей. Таким образом, если вы не можете его уничтожить или каждый из них имеет свой собственный :dependent
, его вызовы могут быть вызваны.
Ответ 2
В ассоциации модели Rails можно указать опцию :dependent
, которая может принимать одну из следующих трех форм:
-
:destroy/:destroy_all
Связанные объекты уничтожаются вместе с этим объектом, вызывая их метод destroy
-
:delete/:delete_all
Все связанные объекты немедленно уничтожаются без вызова метода :destroy
-
:nullify
Внешние ключи всех связанных объектов установлены на NULL
, не вызывая обратные вызовы save
Ответ 3
См. destroy удаляет связанные элементы, где delete_all может удалять несколько данных из собственной таблицы как DELETE * FROM table where field = 'xyz'
: зависимые возможные варианты:
Управляет тем, что происходит с связанными объектами, когда их владелец уничтожен. Обратите внимание, что они реализованы как обратные вызовы, а Rails выполняет обратные вызовы по порядку. Следовательно, другие подобные обратные вызовы могут влиять на зависимое поведение, а поведение :dependent
может влиять на другие обратные вызовы.
:destroy
вызывает также уничтожение всех связанных объектов.
:delete_all
заставляет все связанные объекты удаляться непосредственно из базы данных (поэтому обратные вызовы не будут выполняться).
:nullify
заставляет внешние ключи установить значение NULL. Обратные вызовы не выполняются.
:restrict_with_exception
вызывает исключение, если есть связанные записи.
:restrict_with_error
вызывает ошибку, добавляемую владельцу, если есть связанные объекты.
Если использовать параметр :through
, то ассоциация в модели объединения должна быть принадлежностью, а записи, которые удаляются, - это записи объединений, а не связанные записи.
Ответ 4
На самом деле основное отличие состоит в том, что любые обратные вызовы не будут вызываться, когда используется :delete_all
. Но при использовании :destroy
будет запущен стек обратных вызовов (:after_destroy
, :after_commit
...).
Следовательно, если у вас есть объявления touch:
ing в удаляемых моделях, лучше использовать dependent: :delete_all
скорее "depend:: destroy".