ActionMailer attachments
Disclaimer: Binary attachments seem to be broken on Windows because of a problem with the base64 encoding. See the bug I submitted.
ActionMailer is a curious beast. I spent much of last week debugging and retooling what I thought was already working. In testing sending an email with a binary attachment, I found that the file size was smaller, and that the Word document I was using to test it was corrupted -- it thought the character encoding was Japanese, of all things. Turns out this is not a problem on our Linux server, but only on my local Windows box.
That aside, I took
There's a lot of extra stuff there, like making sure we select
FYI: I'm using Rails 1.1 and the path/filename and content-type information for my email attachments are stored in the database via an ActiveRecord model called
ActionMailer is a curious beast. I spent much of last week debugging and retooling what I thought was already working. In testing sending an email with a binary attachment, I found that the file size was smaller, and that the Word document I was using to test it was corrupted -- it thought the character encoding was Japanese, of all things. Turns out this is not a problem on our Linux server, but only on my local Windows box.
That aside, I took
procreate
's suggestion and looked at some raw emails in my inbox. I wanted to do a gracefully-degrading body content, AND have binary attachments. Below is a snippet of what I came up with. Keep in mind that I'm still dealing with a problem that doesn't allow my templates to be rendered using render_message
, so I broke the MVC pattern and put functions in my mailer that do that for me. (Maybe this is a bug I should submit?)def attachments(myObject)
subject 'Subject'
recipients 'somebody@kckcc.edu'
from 'somebody-else@kckcc.edu'
content_type "multipart/mixed"
# Message body
part :content_type => "multipart/alternative" do |p|
p.part :content_type => "text/html",
:body => html_view(myObject)
p.part :content_type => "text/plain",
:body => text_view(myObject)
end
# Attachments
part :content_type => "multipart/mixed" do |p|
for att in myObject.attachments
enctype = "Base64"
if att.content_type =~ /^(text\/)/
enctype = "Quoted-printable"
end
p.attachment :content_type => att.content_type,
:body => File.read(att.file),
:filename => File.basename(att.file),
:transfer_encoding => enctype,
:charset => "utf-8"
end
end
end
There's a lot of extra stuff there, like making sure we select
Quoted-printable
encoding for text content-types. Also, it's not necessary to place your attachments in a separate part -- they can exist at the same level as your message body. I just did it to make sure they weren't interacting with one another unexpectedly.FYI: I'm using Rails 1.1 and the path/filename and content-type information for my email attachments are stored in the database via an ActiveRecord model called
Attachment
. As always, YMMV.