Reputation: 25102
What is the right way to embed an image into email using Rails?
Upvotes: 74
Views: 43061
Reputation: 4618
I combined the answer from Oksana with a custom helper approach and got the following to work quite nicely.
app/helpers/email_helper.rb
module EmailHelper
def email_image_tag(image, **options)
attachments[image] = File.read(Rails.root.join("app/assets/images/#{image}"))
image_tag attachments[image].url, **options
end
end
app/mailers/base_mailer.rb
class BaseMailer < ActionMailer::Base
helper(EmailHelper)
end
app/mailers/my_mailer.rb
class MyMailer < BaseMailer
def send_my_mail(email)
mail to: email, subject: "My Subject"
end
end
Then for example where I want to attach the company logo in my email layout file I would use
app/views/layouts/email.html.erb
<%= email_image_tag("company_logo.png") %>
Note the **options makes the tag more extensible but it will only work in ruby >=2. To make this work in ruby < 2 you will have to use the older way of handling key word options.
Update 03/25/2022: Rails 6 no longer supports add_template_helper
, and now replaces it with helper
, as explained by this answer that links to the commit that did so.
Upvotes: 86
Reputation: 63
In rails 6, if you use the solution of @Tyron, you'll need to replace add_template_helper
with helper
in the BaseMailer. So, it becomes:
class BaseMailer < ActionMailer::Base
helper(EmailHelper)
end
Upvotes: 1
Reputation: 4593
RAILS 5
In your mail method add your inline attachment pointing to your image:
class ConfirmationMailer < ActionMailer::Base
def confirmation_email
attachments.inline["logo.png"] = File.read("#{Rails.root}/app/assets/images/logo.png")
mail(to: email, subject: 'test subject')
end
end
Then in your mail html view an image_tag
with the attachment url:
<%= image_tag(attachments['logo.png'].url) %>
Upvotes: 57
Reputation: 281
Copy pasted from here
Inline Attachments
You can also specify that a file should be displayed inline with other HTML. This is useful if you want to display a corporate logo or a photo.
class Notifier < ApplicationMailer
def welcome(recipient)
attachments.inline['photo.png'] = File.read('path/to/photo.png')
mail(to: recipient, subject: "Here is what we look like")
end
end
And then to reference the image in the view, you create a welcome.html.erb file and make a call to image_tag passing in the attachment you want to display and then call url on the attachment to get the relative content id path for the image source:
<h1>Please Don't Cringe</h1>
<%= image_tag attachments['photo.png'].url -%>
As we are using Action View's image_tag method, you can pass in any other options you want:
<h1>Please Don't Cringe</h1>
<%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
Upvotes: 8
Reputation: 16957
After a lot of research i have found very cleaner way to embed image in email.
Just add following line in production.rb
and development.rb
config.action_mailer.asset_host = 'YOUR HOST URL'
In your view embed image by using following code.
<%= image_tag('My Web Site Logo.png') %>
Note: Make sure to update YOUR HOST URL and My Web Site Logo.png in above code.
For basic details of usage of Action Mailer, please refer to ActionMailer::Base.
Upvotes: 18
Reputation: 2464
Adding onto Oksana and tdubs' answers
The module tdubs wrote works on desktop, but for the mobile gmail client, the images appeared as attachments. To fix this, do this for the
app/helpers/email_helper.rb
module EmailHelper
def email_image_tag(image, **options)
attachments[image] = {
:data => File.read(Rails.root.join("app/assets/images/emails/#{image}")),
:mime_type => "image/png",
:encoding => "base64"
}
image_tag attachments[image].url, **options
end
end
For the rest, follow tdubs's answer.
Upvotes: 25
Reputation: 3601
I don't know much about rails, but I've worked on projects in C# that create emails and then insert them in a users inbox via the Google APIs. To create the email, I had to generate the email string from scratch. If you enable multipart for the email, then the image bytes will be included in a multipart section using base64 encoding.
You may want to check out the TMail and RubyMail packages to see if they support these actions for you.
Upvotes: -2