ActiveJob无法在`test`环境中找到记录

时间:2016-12-16 07:15:08

标签: ruby-on-rails rspec rails-activejob

此问题仅存在于test环境中。在development环境中,一切运行良好。

最近从Rails 4.2.7.1升级到Rails 5.0.0.1后,我遇到了一个奇怪的问题。升级前一切正常。

在我的一个模型中,我使用ActiveJob来执行任务。

# webhook_invocation.rb

def schedule_invocation
  WebhookRequestJob.perform_later(id)
end

def init
  remember_webhook # No DB changes
  init_errors_context # No DB changes
  flow_step_invocation.implementation = self
  flow_step_invocation.save!

  return unless calculate_expressions  # No DB changes
  calculated! # An AASM event, with no callbacks
  schedule_invocation
end

并在WebhookRequestJob#perform中,我使用提供的ID

检索对象
# webhook_request_job.rb

def perform(webhook_invocation_id)
  invocation = WebhookInvocation.find_by(id: webhook_invocation_id)
  invocation.run_request
end

问题在于#perform,找不到记录(invocation变为nil)。我甚至尝试将p WebhookInvocation.all作为第一行,但它打印的所有内容都是空集合。另一方面,如果我在p WebhookInvocation.all方法中尝试#schedule_invocation,则会正确打印WebhookInvocation的所有对象。

没有异常被提出,也没有警告线。

修改1:

我甚至尝试将对象直接传递给#perform_later,即WebhookRequestJob.perform_later(self),但#perform处收到的对象为nil

编辑2:

我注意到有一些消息,如Creating scope :fail. Overwriting existing method FlowStepInvocation.fail,是由使用AASM引起的。我使用create_scopes: false删除了它们。但这仍然没有解决问题。

2 个答案:

答案 0 :(得分:0)

根据您提供的信息,我猜您已在schedule_invocationafter_save回调中调用after_create方法。由于调用了回调,因此即使在实际持久化对象之前(在COMMIT完成之前),ActiveJob也可能开始处理作业。在这种情况下,处理作业时您的记录不会显示在数据库中,您将获得一个空集合或nil

要解决此问题,请将回调更改为after_commit,以确保在排队作业之前发生了COMMIT操作。

答案 1 :(得分:0)

事实证明,config.active_job.queue_adapter在Rails 5之前默认设置为:inline,但在Rails 5中设置为:async

这使规格失败(不知道为什么)。要解决此问题,我将以下行添加到config/environments/test.rb

config.active_job.queue_adapter = :inline