Поставить задачу ActiveJob в очередь с уничтоженным объектом - PullRequest
0 голосов
/ 30 марта 2019

В действии контроллера я уничтожаю запись и затем передаю ее в качестве аргумента ActiveJob.

def destroy
  post = Post.find params[:id]
  post.destroy
  CleanUpJob.perform_later post
end

И в своей работе мне нужно выполнить некоторые действия по очистке этой уничтоженной записи.

def perform(post)
  log_destroyed_content post.id, post.title
end

Когда я называю его задержанным с .perform_later - он вообще не выполняется. Но когда я перехожу на .perform_now - он работает как положено. Эта работа должна иметь дело как с уничтоженными, так и с сохраненными записями.

Я использую последние Rails, среду разработки с адаптером async activejob по умолчанию.

Ответы [ 2 ]

2 голосов
/ 31 марта 2019

Когда вы вызываете .perform_later с ActiveRecord объектом, ActiveJob попытается сериализовать его в глобальный идентификатор

. Вы удаляете свою запись из базы данных, котораяозначает, что ваша работа не найдет ее при запуске.

Вы можете передать хеш со всеми атрибутами: CleanUpJob.perform_later(post.attributes)

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

# in the controller
def destroy
  post = Post.find params[:id]
  post.update(state: :archived) # or whatever makes more sense for your application
  CleanUpJob.perform_later(post.id, post.title)
end

# in the job
def perform(post_id, post_title)
  log_destroyed_content(post_id, post_title)
  post.destroy
end

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

1 голос
/ 31 марта 2019

Вместо прохождения уничтоженного post просто передайте его id и title.

# in the controller
def destroy
  post = Post.find params[:id]
  post.destroy
  CleanUpJob.perform_later(post.id, post.title)
end

# in the job
def perform(post_id, post_title)
  log_destroyed_content(post_id, post_title)
end
...