I have a Mailer class which inherits from ApplicationMailer, which in turn inherits from ActionMailer::Base. Ruby version is ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin15]
.
The Mailer class looks like the following:
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 looks like the following:
# 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
The view is located at app/views/purchase_order_status_mailer/daily_report_email.html.erb
.
When I open my Rails console and type PurchaseOrderStatusMailer.new.daily_report_email('JC').deliver
, I see the following error:
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'
I tried passing a format
block to the call to the mail
helper with the same call, like so:
mail(to: CONTACTS[facility.to_sym], subject: "#{facility} Daily Receipt Status - #{Date.today}") do |format|
format.text { render plain: "Hey!" }
end
The above produced the following response, which appears to represent a successful email send:
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>>
I didn't actually receive an email, and I assume that means I don't have SMTP set up on my local machine, but the above response is encouraging. There was no stack trace apart from the error I posted above, so I tried digging into the Rails source code, and I saw that normalize_name
inside lookup_context.rb
gets called from within the args_for_lookup
protected method, which in turn gets called by the ViewPaths
module's find_all
method. But beyond that it was hard to trace the call stack, as I couldn't find who the caller of find_all
is.
My question is: what is wrong with the first call to mail
?
EDIT 1: I also tried format.html { render html: "<h1>Hello Mikel!</h1>".html_safe }
instead of the format.text
option, as per the example here, and I got a similar success message.
I then tried adding a byebug statement inside normalize_name
, to try and identify what the values of the parameters were on the successful email sends, but it looks like this method isn't getting called when a block is passed. That makes me suspect even more strongly that the problem is somehow related to my views. But I can't confirm that yet.
I was able to generate a success
response (including my mailer's rendered template file) by passing template_path
and template_name
options to the original call to the mail
helper, like so:
mail(
to: CONTACTS[facility.to_sym],
subject: "#{facility} Daily Receipt Status - #{Date.today}",
template_path: 'purchase_order_status_mailer',
template_name: 'daily_report_email')
This generated the following success response:
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>>
I'm a little confused about why I had to add these options, as the documentation doesn't make it clear that these are required and my templates and folders appear to be named correctly, but it worked and I have deadlines so I'm moving on. :-)