Исправлено обновление метода 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 вызывает добавление ошибки владельцу, если есть связанные объекты.