Обработка зависимого уничтожения через активные задания

У меня есть многодетная пара моделей. Зависимое уничтожение стало очень тяжелым. Кто-нибудь знает способ связать зависимое уничтожение с активными заданиями? Или мой единственный вариант удалить зависимое уничтожение и роль моих собственных заданий с помощью обратных вызовов в родительской модели?


person hellion    schedule 21.03.2015    source источник
comment
Вы рассматривали возможность пометить свои модели как уничтоженные и фактически удалить их из базы данных асинхронно?   -  person phoet    schedule 21.03.2015
comment
Ты имеешь в виду ставить детей в очередь на уничтожение на работе? Вот над чем я работаю. ActiveJob довольно новый ... может быть, когда-нибудь появится способ рельсов для обработки зависимых: :destroy async с простой опцией ассоциации. На данный момент я ставлю каждую дочернюю модель в очередь на уничтожение и использую потерянный parent_id в качестве тега.   -  person hellion    schedule 21.03.2015
comment
я обычно не удаляю записи из базы данных, так как операции удаления плохо масштабируются. в большинстве случаев дешевле просто пометить записи как удаленные и оставить их там.   -  person phoet    schedule 21.03.2015


Ответы (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, чтобы поставить его в очередь. Вы даже можете пометить объект как удаленный перед тем, как поставить его в очередь, чтобы предотвратить его извлечение из БД до того, как он будет фактически уничтожен.

Не уверен, что это будет работать как есть, но просто чтобы дать вам представление о том, что вы можете сделать.

person lsdr    schedule 23.04.2015

Rails не делает этого изначально. Тем не менее, этот гем хорошо справляется с исправлением ошибок N+1, связанных с зависимым: :destroy. На самом деле он использует depend: :delete_all, но использует его таким образом, что все подклассы также удаляются. И делает это, используя всего 2 обращения к БД на класс. Я не могу поверить, что подобная функциональность не включена в ядро ​​​​rails. https://github.com/jisaacks/recurse-delete

person hellion    schedule 22.03.2015

В версии 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/

person justcode    schedule 14.03.2021