Можно ли сохранить отслеженные изменения в модели, переданные отложенному заданию? - PullRequest
0 голосов
/ 24 декабря 2018

Я хочу выполнить некоторые дорогостоящие операции, когда моя модель изменится, поэтому я делаю это асинхронно в отложенной работе.Внутри этой работы мне нужно иметь возможность сказать, какие именно изменения произошли, поэтому я передаю измененную модель в качестве параметра отложенному заданию.

Теперь кажется, что отложенное задание извлекает новое(нетронутая) версия модели из базы данных при запуске задания, в которой нет отслеженных изменений, которые мне нужны.

class MyModel < ActiveRecord::Base
    after_save :perform_async_job

    def perform_async_job
        # Here, "self.changes" contains the changes
        Delayed::Job.enqeue(AsyncJobPerformer.new(self), ...)
    end
end

class AsyncJobPerformer
    def initialize(model)
        @model = model
    end

    def perform
        # Here, "@model.changes" is empty
    end
end

Я могу, конечно, передать только хэш changes, а не саму модель, но это сделает код отложенного задания гораздо более сложным, так как ему все равно нужно использовать экземпляр модели(поэтому мне нужно извлечь его и использовать модель и изменения как отдельные объекты).

Есть ли способ передать модель отложенному заданию при сохранении отслеженных изменений?

1 Ответ

0 голосов
/ 24 декабря 2018

Никогда не отправляйте модельные объекты работникам, просто отправляйте идентификаторы.Вам нужно будет передать хэш изменений.Работник не сможет сохранить изменения, созданные экземпляром объекта.Так что да, вам нужно будет передать изменения вашему работнику.

class MyModel < ActiveRecord::Base
  after_save :perform_async_job

  def perform_async_job
    # Here, "self.changes" contains the changes
    Delayed::Job.enqeue(AsyncJobPerformer.new(self.class.name, self.id, self.changes), ...)
  end
end

class AsyncJobPerformer
  def initialize(model_name, model_id, params)
    changes = params
    @model = model_name.constantize.find(model_id)
    #handle changes here with @model.update(changes) or a seperate method if need.
  end

  def perform
    # Here, "@model.changes" is empty
  end
end
...