We have been working on a mailing service for a while now and we really like what we can do with html emails. Unfortunately, with the plethora of smart phones these days, HTML support is inconsistent. We figured that a good stop-gap solution was to offer both HTML and text versions of an email. Preferably in one package.
And that’s where multipart emails come in.
Suprisingly (or not), this was rather easy to implement in Rails 2.3.
There are two ways of doing this. Implicit and explicit multipart emails. I decided to go with the former.
All I had to do was to make sure the content type is set correctly:
content_type “multipart/alternative”
Then, I just had to make sure my template file ends with the right signature “foo.text.plain.erb” and “foo.text.html.erb” for plain text and html emails respectively.
See the multipart email section in the official doc here: http://api.rubyonrails.org/classes/ActionMailer/Base.html
I used a controller to trigger the email and it all worked just like a charm. I had my email with both text and html components. I checked in the code, fired up my mailer service which runs in backgroundrb and called it a day.
That’s when I saw this error popping up:
can’t convert nil into String
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb:551:in `quote’
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb:551:in `read_multipart’
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb:540:in `parse_body_0′
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb:522:in `parse_body’
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb:476:in `body=’
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:650:in `create_mail’
…
After some investigation, I figure that this is one of those things where backgroundrb is incompatible with a certain feature of rails. I considered fudging around with the tmail code but gave up on that endeavor quickly. Instead, I decided to work around with an explicit version of the multipart email. To my delight, that worked perfectly.
content_type “multipart/alternative”
part :content_type => “text/plain”,:body => render_message(”foo.text.plain”, :variable1=>variable1, :variable2 => variable2)part :content_type => “text/html”,:body => render_message(”foo.text.html”, :variable1=>variable1, :variable2 => variable2)
Be sure to declare text/plain and text/html in that order. Email clients like Gmail may not offer the text alternative or show the HTML version automatically if you change that order.
The template files work as-is without any modifications. Well, crisis averted. Back to making some barcodes. :)