Ruby on Rails mailer

Today I made a first attempt to make use of ruby mailer. A volunteer
fills out a form and the information is then sent to an administrator.

I generated a mailer called notifier and added the following:

class Notifier < ActionMailer::Base
def volunteer_signup(volunteer, sent_at = Time.now)
@subject = ‘A new volunteer has signed up’
@body = { :title => volunteer.title, :first_name =>
volunteer.first_name, :last_name => volunteer.last_name,
:id => volunteer.id }
@recipients = ‘[email protected]
@from = ‘[email protected]
@sent_on = sent_at
@headers = {}
@content_type = ‘text/html’
end
end

Then I generated a view called volunteer_signup.html.erb

Dear xxx,

<%= @title %><%= @first_name %> <%= @last_name %> has signed up as a
new volunteer.

To see his/her information copy the text below into your browser’s
address bar.
http://localhost:3000/volunteers/<%= @id %>

I added the following line to my volunteer_controller create method:

Notifier.deliver_volunteer_signup(@volunteer)

I ran the code and got the following error:

mailer sub type missing: “html”

I ran the debugger and noticed the following;

At /usr/lib/ruby/gems/1.8/gems/actionmailer-2.0.1/lib/action_mailer/
part.rb:59:in ‘to_mail’

59: real_content_type, ctype_attrs = parse_content_type(defaults)

This method takes the content_type of the message “text/html” and
splits the string so that variable real_content_type is “html”. But
then on line 82 it calls;

82: part.set_content_type(real_content_type, nil, ctype_attrs)

def set_content_type( str, sub = nil, param = nil )
if sub
main, sub = str, sub
else
main, sub = str.split(%r</>, 2)
raise ArgumentError, “sub type missing: #{str.inspect}” unless
sub
end
if h = @header[‘content-type’]
h.main_type = main
h.sub_type = sub
h.params.clear
else
store ‘Content-Type’, “#{main}/#{sub}”
end
@header[‘content-type’].params.replace param if param
str
end

As you can str contains “html” as real_content_type was passed in, sub
is nil. It then tries to split this string again, which has been
split before. So str will be split into “html” and nil. Since sub is
nil, it will raise the error. If I leave @content_type blank, the
same error is raised.

Could this be a bug in mailer? If you change str or real_content_type
to “text/html” in the debugger, the code will run without errors. I’m
new to Ruby on rails, so if this is a bug, please let me know where I
should submit it.

Are you using the globalize plugin? Apparently if you comment out
‘require “globalize/rails/action_mailer”’ in vendor/plugins/globalize/
init.rb the error goes away… or maybe try updating the plugin if they
fixed the bug yet…

I tried updating the plugin but bug isn’t fixed. Your suggestion
works though.

Hi Franz,
instead of commenting out the globalize/rails/action_mailer and
disabling the ability to send Mails in different languages hereby, you
should extend your email templates with the locale parameter. For
example english templates should look like this:

signup_notification.en.text.plain.erb
signup_notification.en.text.html.erb

Globalize overrides the Action Mailers create-Method giving it the
ability to check for multilanguage extentions, as well as the new
Action Mailer(2.0.2) is checking for multipart email extentions.
So there is no bug anywhere. Everything will work fine.

For more information read the Rails API, section Multipart email of
ActionMailer::Base Class

Best wishes,
Roman

Franz,

Roman’s answer hits the nail on the head. I had the same problem and
this is exactly what I also concluded. Follow naming convention for
localized mailer templates:

<mailer_method>.[.]<mime_type>..erb

Ex.: activation.en-US.text.html.erb

Docs (vendor/plugins/globalize/lib/globalize/rails/action_mailer.rb)

Globalize overrides the create! method to support multiple templates
for different locales.
For example, for English it will select the template:

signup_notification.en-US.text.html.rhtml

It will look for the currently active locale code (en-US) first, then
the language code (en).

If neither of those are found, it will use the regular name:

signup_notification.text.html.rhtml

It is fully backwards compatible with the original Rails version.

Cheers, Sazima