【问题标题】:ActiveJob::DeserializationError in a after_create callback - Record Not Foundafter_create 回调中的 ActiveJob::DeserializationError - 未找到记录
【发布时间】:2020-02-14 10:06:14
【问题描述】:

在 Rails 6 应用程序中,我有以下代码。

class Reservation < ApplicationRecord
  after_create     :publish_creation

  def publish_creation
    Publishers::Reservations::CreateJob.perform_later(self)
  end
end

class Publishers::Reservations::CreateJob < ApplicationJob
  queue_as :default

  def perform(reservation)
    puts reservation.inspect #dummy code for testing
  end
end

大多数时候我创建一个Reservation(记录总是在数据库中创建),我得到下面的错误

2020-02-14T09:54:03.707Z pid=81787 tid=1xmj 警告: ActiveJob::DeserializationError: Error while trying to deserialize arguments: Couldn't find Reservation with 'id'= 35651cf7-35bc-4da0-bb0d-6285ac093d22

Sidekiq 第一次重试处理作业时,它总是找到Reservation 并且一切正常。

Reservation id: "35651cf7-35bc-4da0-bb0d-6285ac093d22", analysis_id: "6b3b167b-1279-49c0-991a-b580c375fd0f", reservable_type: "User", reservable_id: "94f60c16-29d4-4372-983b-7544c393a7e6", reserved_between: 2020-02-10 08:00:00 UTC..2020-02-10 08:10:00 UTC, state: "scheduled", created_at: "2020-02-14 10:02:28", updated_at: "2020-02-14 10:02:28"

我在这里遗漏了什么吗? 这是否与我在development 模式下运行的事实有关,一旦我移动到production,它就会消失?

【问题讨论】:

    标签: ruby-on-rails sidekiq


    【解决方案1】:

    您应该使用after_commit 而不是after_create。这是因为

    after_create - 在 Model.save 之后调用尚未保存的新对象(不存在记录)。对于after_create,这将始终在调用保存(或创建)返回之前。 Rails 将每个保存都包装在事务中,并且创建前后的回调在该事务中运行。

    after_commit - 在数据库事务完成后调用。使用after_commit,您的代码在提交最外层事务之前不会运行。

    【讨论】:

      【解决方案2】:

      在 Rails 5+ 中,您可以使用 after_create_commit (docs)

      它将在创建事务之后运行,因此记录已经创建,但与after_commit 不同,它只会在create 之后运行,而不是在updatedestroy 之后运行。

      这是一个别名: after_commit :your_callback, on: :create

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-09
        • 1970-01-01
        • 2012-05-20
        • 2019-10-31
        • 2021-12-23
        • 1970-01-01
        相关资源
        最近更新 更多