Benito Serna Helping you be better with Ruby on Rails

How to attach an active storage file to an email

Are you using Active Storage to handle file uploading to the cloud (maybe AWS) and you want to know how to attach an uploaded file to an email?… But you are not familiar with the Active Storage and Action Mailer APIs?

I answered this question on reddit some days ago =)… Here is how you can do it…

You need to download the file and assign as and attachment, something like this…

attachments[photo.filename.to_s] = photo.download

Here the context of the example…

class Product < ApplicationRecord
  has_one_attached :photo
end

class PhotoMailer < ApplicationMailer
  default from: "default@example.com"

  def new_photo_email
    photo = params[:product].photo
    attachments[photo.filename.to_s] = photo.download
    mail(to: "one@example.com", subject: "Nueva photo")
  end
end

class PhotoMailerPreview < ActionMailer::Preview
  def new_photo_email
    PhotoMailer.with(product: Product.first).new_photo_email
  end
end

Here the reference from the rails guides https://edgeguides.rubyonrails.org/activestorageoverview.html#downloading-files

Why using “download” works?

If you are not familiar with Action Mailer and you are reading the docs, maybe is not that clear what you need to do. Here is what I understand.

On the Action Mailer docs you can see…

attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

Inside the [] you need to put the name that you want for the attachment and you need to assign the content of the file. Like this:

attachments[filename] = file_content

In the example from the docs, File.read returns the content of the file.

Now, in the ActiveStorage docs says that you can “Use the attachment’s download method to read a blob’s binary data into memory”, and they use this example:

binary = user.avatar.download

That’s why I propose you to use download. Apparently download will return the content of the file wherever the file is stored.

Related articles