Rails 6 & Deliver_later 不影响 ActionMailer::Base.deliveries

Posted

技术标签:

【中文标题】Rails 6 & Deliver_later 不影响 ActionMailer::Base.deliveries【英文标题】:Rails 6 & deliver_later doesn't affect ActionMailer::Base.deliveries 【发布时间】:2020-01-06 14:53:05 【问题描述】:

升级到 Rails 6 后,我注意到默认邮件程序的 .deliver_later 与 Rails 5 中的工作方式不同。

配置:

config.active_job.queue_adapter = :inline

运行Mailer.register_email(...).deliver_later 时,ActionMailer::Base.deliveries 中没有存储任何内容。如果我运行perform_enqueued_jobs,这个数组就会被填满——它看起来像queue_adapter = :inline 并没有按照我期望的方式工作。

如果我运行Mailer.send(...).deliver_now,那么ActionMailer::Base.deliveries 就有适当的价值。

知道为什么会发生这种情况以及如何解决这个问题吗?

【问题讨论】:

这种行为在 Rails 5 和 Rails 6 之间发生了变化。我找不到在哪里,但我确实看到 Rails 现在在他们的 Minitest 电子邮件帮助程序中调用perform_enqueued_jobs。他们添加了一个过滤器以确保仅以这种方式执行电子邮件作业。 github.com/rails/rails/blob/master/actionmailer/lib/… 【参考方案1】:

我在测试中遇到了同样的问题。在互联网上搜索没有任何结果,所以我开始尝试。

我尝试将发送邮件的调用方法封装在

assert_emails 1 do
  Mailer.register_email(...).deliver_later
end

之后,ActionMailer::Base.deliveries 填充正确。

【讨论】:

【参考方案2】:

如果电子邮件的确切数量很容易改变,这是另一种选择:

assert_changes 'enqueued_jobs.size' do
  # Some code that sends email with deliver_later
end

这允许您测试是否发送了电子邮件,但它忽略了确切的数字(这是 asserts_emails 方法的限制 - 除此之外,asserts_emails 方法很棒)。 我发现enqueued_jobs 方法对于测试任何后台作业非常有帮助,包括deliver_later

注意:以上示例仅检查入队作业列表是否已更改。如果您想更具体并检查队列是否已随电子邮件更改,您应该这样做:

assert_changes 'enqueued_jobs.select |job| job["job_class"] == "ActionMailer::MailDeliveryJob".size' do
  # Some code that sends email with deliver_later
end

【讨论】:

以上是关于Rails 6 & Deliver_later 不影响 ActionMailer::Base.deliveries的主要内容,如果未能解决你的问题,请参考以下文章

jQuery、webpacker 和 Rails 6 事件监听器

rails 服务器无法在 OSX 10.6.5 上使用 rvm 和 ruby​​ 1.9.2-p0 启动 mysql2

Uncaught ReferenceError: $ is not defined in Rails 6 webapp search bar

Rails 异常处理 && 性能

Ruby / Rails 4.2 - 如果A && B,其中B条件取决于Rails环境

在转换为UTC 0时区之前,Rails在哪里获得时区?