Peter Bohm wrote: > which way do you send the email? Using the raw TMail object as described
> in the HowToSendMimeMultipartEmailsWithActionMailer? Can you post some
code?
I''ll describe the problem in a bit more detail, and then will describe
what I did to solve it.
The site I''m working on wanted to send an acknowledgment to people
using our e-commerce site. The message itself needed to be in HTML, in part to
(nicely) display a list of purchased items. But the message also needed to
include a PDF file with a mailing label for sending something back to the site
via the post office. So I was looking to create an e-mail message with one
segment with a MIME type of text/html, and another with a MIME type of
application/pdf.
The methods described in the "Agile development" book describe how to
create a message of a single MIME type, either text/plain or text/html.
I''ve been working with e-mail for a while, so I knew that any message
containing both HTML and PDF would need to be multipart/mixed, with what
essentially amounts to two attachments.
The thing is, it wasn''t at all obvious how to create such a message.
The HowToSendEmailsWithActionMailer page on the Rails Wiki mentioned that recent
versions of Rails include an "attachment" method that can be invoked
from within a subclass of ActionMailer::Base. This sounded pretty good, but I
was a bit worried about the results (and rightly so, it turned out. I ended up
doing something like this in my mail method:
def confirmation_message(order, person, payment_method, label)
@subject = "Confirming order ##{order.id}"
@from =
''orders-NKvcMekWyJVWk0Htik3J/w@public.gmane.org''
@recipients = person.email_address
attachment(:content_type => ''application/pdf'',
:filename => "mailing-label.pdf",
:body => label.render)
end
I then did something like the following:
email = create_confirmation_message(@order, @person, @payment_method, label)
email.set_content_type("multipart/mixed")
But when I would send the mail, the HTML portion would disappear.
When I used the technique described on the
HowToSendMimeMultipartEmailsWithActionMailer page of the Wiki, creating a raw
TMail object, I had all sorts of weird problems that I can''t remember
offhand; sometimes the PDF would arrive with odd (probably 8-bit) characters
that crashed the OS X Preview application, sometimes the HTML wouldn''t
appear.... basically, I got a variety of different errors.
After thinking for a while, I finally realized that I should return to the first
technique, passing both the label and the HTML as parameters to the
confirmation_message method. This meant generating the HTML before I actually
created the message. This seems to work quite nicely.
In practice, this looks like the following:
class OrderMailer < ActionMailer::Base
def confirmation_message(person, label, html)
@recipients = person.email_address
@from = "orders-NKvcMekWyJVWk0Htik3J/w@public.gmane.org"
@subject = "Thank you for ordering from MyDomain.com"
attachment "text/html" do |a|
a.body = html
end
attachment "application/pdf" do |a|
a.body = label.render
a.filename = "mailing-label.pdf"
end
end
end
I then invoke the above method from my controller as follows:
def generate_confirmation_email
label = create_mailing_label(@order, @person)
html = render_to_string(:template => "order_mailer/confirm",
:layout => "blank")
OrderMailer::deliver_confirmation_message(@person, label, html)
end
And voila, it works! (Note that I created a "blank" layout, so as to
avoid the headers and footers from the rest of the site.)
The bottom line: If you want to have HTML and something else in a message,
generate the HTML and PDF *before* invoking the send_* method. Perhaps
there''s a better and/or easier way, but now that I''ve started
to work with this code, it seems pretty straightforward to me.
Reuven