У меня есть многодетная пара моделей. Зависимое уничтожение стало очень тяжелым. Кто-нибудь знает способ связать зависимое уничтожение с активными заданиями? Или мой единственный вариант удалить зависимое уничтожение и роль моих собственных заданий с помощью обратных вызовов в родительской модели?
Обработка зависимого уничтожения через активные задания
Ответы (3)
Вы можете создать рабочего, чтобы асинхронно уничтожить модели и поставить их в очередь на удаление. Что-то типа:
class ComplexModelDeletion < ActiveJob::Base
def perform(model)
model.destroy!
end
end
И модель может быть примерно такой:
class Model < ActiveRecord::Base
def destroy_later
ComplexModelDeletion.enqueue(self)
end
end
Затем, всякий раз, когда вам нужно убить экземпляр этой модели, вы можете вызвать Model#destroy_later
, чтобы поставить его в очередь. Вы даже можете пометить объект как удаленный перед тем, как поставить его в очередь, чтобы предотвратить его извлечение из БД до того, как он будет фактически уничтожен.
Не уверен, что это будет работать как есть, но просто чтобы дать вам представление о том, что вы можете сделать.
Rails не делает этого изначально. Тем не менее, этот гем хорошо справляется с исправлением ошибок N+1, связанных с зависимым: :destroy. На самом деле он использует depend: :delete_all, но использует его таким образом, что все подклассы также удаляются. И делает это, используя всего 2 обращения к БД на класс. Я не могу поверить, что подобная функциональность не включена в ядро rails. https://github.com/jisaacks/recurse-delete
В версии 6.1.0 Rails теперь имеет встроенную поддержку. Вы можете добавить dependent: :destroy_async
к отношению, и рельсы обработают удаление в фоновом режиме. Смотрите блог здесь — https://weblog.rubyonrails.org/2020/10/3/this-week-in-rails-destroying-associations-asynchronously-interval-datatype-and-more/