尝试通过 Rails ActionMailer 发送电子邮件导致对 `lookup_context.rb` 中的 `normalize_name` 的调用失败

Attempt to send an email via Rails ActionMailer results in a failed call to `normalize_name` inside `lookup_context.rb`

我有一个 Mailer class,它继承自 ApplicationMailer,后者又继承自 ActionMailer::Base。 Ruby 版本为 ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin15].

邮件程序 class 如下所示:

class PurchaseOrderStatusMailer < ApplicationMailer
  CONTACTS = {
    JC: ['me@example.com'],
    RM: ['me@example.com']
  }

  def daily_report_email(facility)
    @facility = facility
    ingredient_items = LineItem.ingredient.by_facility(facility)
    @delivered_count = ingredient_items.by_date([7.days.ago, 7.days.from_now]).delivered.count
    @partial_count = ingredient_items.by_date([7.days.ago, 1.day.ago]).partial.count
    @late_count = ingredient_items.by_date([7.days.ago, 1.day.ago]).late.count
    @expected_count = ingredient_items.by_date([Date.today, 7.days.from_now]).expected.count
    mail(to: CONTACTS[facility.to_sym], subject: "#{facility} Daily Receipt Status - #{Date.today}")
  end
end

ApplicationMailer 如下所示:

# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
  default from: 'notify@example.com'

  def facility_email(facility)
    emails = Rails.application.config_for(:emails)
    (emails[facility] + emails["DEFAULT"]).flatten
  end
end

视图位于 app/views/purchase_order_status_mailer/daily_report_email.html.erb

当我打开 Rails 控制台并键入 PurchaseOrderStatusMailer.new.daily_report_email('JC').deliver 时,我看到以下错误:

NoMethodError: undefined method `empty?' for nil:NilClass
from /Users/me/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actionview-5.0.4/lib/action_view/lookup_context.rb:215:in `normalize_name'

我尝试将 format 块传递给使用相同调用的 mail 帮助器的调用,如下所示:

mail(to: CONTACTS[facility.to_sym], subject: "#{facility} Daily Receipt Status - #{Date.today}") do |format|
  format.text { render plain: "Hey!" }
end

上面产生了以下响应,这似乎代表电子邮件发送成功:

  Rendering text template
  Rendered text template (0.0ms)
Sent mail to me@example.com (8.8ms)
Date: Mon, 25 Sep 2017 12:55:11 -0400
From: notify@example.com
To: me@example.com
Message-ID: <59c934efec401_1115b3fd69cc3f840917be@me-MBP.mail>
Subject: JC Daily Receipt Status - 2017-09-25
Mime-Version: 1.0
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Hey!
=> #<Mail::Message:70191029273300, Multipart: false, Headers: <Date: Mon, 25 Sep 2017 12:55:11 -0400>, <From: notify@example.com>, <To: ["me@example.com"]>, <Message-ID: <59c934efec401_1115b3fd69cc3f840917be@me-MBP.mail>>, <Subject: JC Daily Receipt Status - 2017-09-25>, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: 7bit>>

我实际上没有收到电子邮件,我认为这意味着我没有在我的本地计算机上设置 SMTP,但以上回复令人鼓舞。除了我在上面发布的错误之外没有堆栈跟踪,所以我尝试深入研究 Rails 源代码,我看到 lookup_context.rb 中的 normalize_name 是从 [=25] 中调用的=] protected 方法,它又被 ViewPaths 模块的 find_all 方法调用。但除此之外,很难跟踪调用堆栈,因为我找不到 find_all 的调用者是谁。

我的问题是:第一次调用 mail 有什么问题?

编辑 1:根据示例 here,我还尝试了 format.html { render html: "<h1>Hello Mikel!</h1>".html_safe } 而不是 format.text 选项,并且我收到了类似的成功消息。

然后我尝试在 normalize_name 中添加一个 byebug 语句,以尝试确定成功发送电子邮件时参数的值是什么,但看起来这个方法在块时没有被调用通过了。这让我更加怀疑这个问题与我的观点有某种关联。但我还不能确认。

通过将 template_pathtemplate_name 选项传递给对 mail 的原始调用,我能够生成 success 响应(包括我的邮件程序呈现的模板文件)帮手,像这样:

mail(
  to: CONTACTS[facility.to_sym],
  subject: "#{facility} Daily Receipt Status - #{Date.today}",
  template_path: 'purchase_order_status_mailer',
  template_name: 'daily_report_email')

这生成了以下成功响应:

  Rendering purchase_order_status_mailer/daily_report_email.text.erb
  Rendered purchase_order_status_mailer/daily_report_email.text.erb (0.3ms)
Sent mail to me@example.com (12.1ms)
Date: Mon, 25 Sep 2017 15:18:25 -0400
From: notify@example.com
To: me@example.com
Message-ID: <59c9568121cec_11e943fee8503f82823542@me-MBP.mail>
Subject: JC Daily Receipt Status - 2017-09-25
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="--==_mimepart_59c9568120033_11e943fee8503f8282341e";
 charset=UTF-8
Content-Transfer-Encoding: 7bit


----==_mimepart_59c9568120033_11e943fee8503f8282341e
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Please find the receipt status for JC as of 09-25-2017:
=================================================================================================

...<lots more content, including ERB rendered into HTML>...

=> #<Mail::Message:70293683934580, Multipart: true, Headers: <Date: Mon, 25 Sep 2017 15:18:25 -0400>, <From: notify@example.com>, <To: ["me@example.com"]>, <Message-ID: <59c9568121cec_11e943fee8503f82823542@me-MBP.mail>>, <Subject: JC Daily Receipt Status - 2017-09-25>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_59c9568120033_11e943fee8503f8282341e"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>

我对为什么必须添加这些选项感到有点困惑,因为 the documentation 没有明确说明这些是必需的,而且我的模板和文件夹似乎已正确命名,但它确实有效我有最后期限,所以我要继续前进。 :-)

问题在这里

PurchaseOrderStatusMailer.new.daily_report_email('JC').deliver

删除新的即

PurchaseOrderStatusMailer.daily_report_email('JC').deliver

由于对象错误无法推导模板path/file