Adding multiple email attachments with Ruby on Rails

Published on June 20, 2007

I was building some forms for a client that required the user be able to upload supporting documents along with the application. I had implemented emailable forms before with single attachments, but never multiple. Turns out, it was just as simple to do, I just needed to call the attach function for each file I wanted to attach.

Here is the method in my controller that calls the ActionMailer class to send the email, where params[:attachment1], params[:attachment2], and params[:attachment3] are the file_field_tag's from the form:

def submit_application
  CenterMailer.deliver_email_with_attachments(params[:application],params[:attachment1],params[:attachment2],params[:attachment3])
  flash[:notice] = 'Your application has been submitted.  Thank you!'
  redirect_to application_home_url and return
rescue Exception => ex
  logger.warn(ex.message)
  flash[:notice] = 'Uh oh!  There was an error sending your application.'
  redirect_to :back
end

And here is the ActionMailer method that attaches the files. I just need to call attach for each file and it creates a new attachment.

def email_with_attachments(application_fields={},attachment1=nil,attachment2=nil,attachment3=nil)
  @headers = {}
  @sent_on = Time.now
  @recipients = 'client@domain.com'
  @from = 'info@domain.com'

  @subject = 'Here are some file attachments'
  application_fields.keys.each {|k| @body[k] = fields[k]}

  # attach files
  unless attachment1.nil?
    attachment "application/octet-stream" do |a|
      a.body = attachment1.data
      a.filename = attachment1.name
    end
  end
  unless attachment2.nil?
    attachment "application/octet-stream" do |a|
      a.body = attachment2.data
      a.filename = attachment2.name
    end
  end
  unless attachment3.nil?
    attachment "application/octet-stream" do |a|
      a.body = attachment3.data
      a.filename = attachment3.name
    end
  end
end

The "application/octet-stream" is the generic MIME type for attaching unknown file types.

Pretty simple!

Tagged: actionmailer, email attachment, rails


Shawn Veader said 5 days later:

Nice... You could also compact it some by collecting the attachments together in an array and just iterate over them adding each as an attachment. The #compact method on an array would squash out any nils too.

Leave a comment:




©2008 Travis Roberts. All rights reserved.