Исправлено обновление метода ActiveRecord delete_all вместо удаления
Я использую полиморфные ассоциации Rails, поэтому некоторые модели имеют много детей cash_histories
, например:
has_many :cash_histories, as: :cashable
Но когда я пытаюсь удалить все истории наличных денег из родительского @resource
, вот так:
@resource.cash_histories.delete_all
Я получаю следующий запрос:
UPDATE "cash_histories" SET "cashable_id" = NULL WHERE "cash_histories"."cashable_id" = $1 AND "cash_histories"."cashable_type" = $2 [["cashable_id", 1], ["cashable_type", "ServiceOrder"]]
Я не могу понять это поведение, установив идентификатор отношения к null вместо удаления, что приведет к мертвым строкам в моей таблице. Почему это происходит?
Я использую Rails 4.1.
Ответы
Ответ 1
В документах Rails API для delete_all
:
Удаляет все записи из коллекции. Для ассоциаций has_many удаление выполняется в соответствии со стратегией, указанной опцией: depend. Возвращает массив с удаленными записями.
Если задана опция: зависимая, она будет следовать стратегии по умолчанию. Стратегия по умолчанию: nullify. Это устанавливает внешние ключи в NULL. Для, has_many: through, стратегия по умолчанию - delete_all.
Таким образом, вам просто нужно установить для параметра :dependent
на has_many
значение :delete_all
или :destroy
, в зависимости от того, какое поведение вы хотите.
has_many :cash_histories, as: :cashable, dependent: :delete_all
В документах Rails API для has_many
:
Объекты будут уничтожены, если они связаны с зависимыми:: destroy и удалены, если они связаны с зависимым:: delete_all.
Ответ 2
его все еще странно, потому что везде он всегда описывает, что происходит, когда владелец уничтожается.
Управляет тем, что происходит с связанными объектами, когда их владелец уничтожено:
: destroy приводит к уничтожению связанных объектов.
: delete_all заставляет связанные объекты удаляться непосредственно из базы данных (обратные вызовы не выполняются).
: nullify заставляет внешние ключи быть установленными в NULL (обратные вызовы не выполняются).
: restrict_with_exception вызывает исключение, если возникают связанные записи.
: restrict_with_error вызывает добавление ошибки владельцу, если есть связанные объекты.