What is the right way to embed image into email using Rails?

Ruby on-RailsActionmailer

Ruby on-Rails Problem Overview


What is the right way to embed an image into email using Rails?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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.

Solution 2 - Ruby on-Rails

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) %>

Solution 3 - Ruby on-Rails

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.

Solution 4 - Ruby on-Rails

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.

Solution 5 - Ruby on-Rails

Copy pasted from here

http://api.rubyonrails.org/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Inline+Attachments

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' -%>

Solution 6 - Ruby on-Rails

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

Solution 7 - Ruby on-Rails

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexey ZakharovView Question on Stackoverflow
Solution 1 - Ruby on-RailsTyrone WilsonView Answer on Stackoverflow
Solution 2 - Ruby on-RailsJoelView Answer on Stackoverflow
Solution 3 - Ruby on-RailsPavan KatepalliView Answer on Stackoverflow
Solution 4 - Ruby on-RailsAamirView Answer on Stackoverflow
Solution 5 - Ruby on-Railsstrohy1210View Answer on Stackoverflow
Solution 6 - Ruby on-RailsMohamed ABDELLANIView Answer on Stackoverflow
Solution 7 - Ruby on-RailsregexView Answer on Stackoverflow