🚀 See the 2024 Ruby on Rails Community Survey results!
Article  |  Development

Actionmailer: Is It the Best Way to Send Emails from a Ruby App?

Reading time: ~ 3 minutes

Actionmailer: Is It the Best Way to Send Emails from a Ruby App?

This post is a guest contribution from our friends at Mailtrap, a product that helps people inspect and debug emails before sending them to real users. We’ve used Mailtrap in many of our Rails client projects and can vouch for how helpful their product is.


If you need to implement email delivery from your Ruby app, you can use the Net::SMTP class for that. This, however, is a rather minimalistic solution. That’s why any experienced Rubyist would prefer to make use of a dedicated gem. Since there are a few of them, we’ll take the most common one – ActionMailer – and today, we’ll check out whether it’s the best way to send emails with Ruby.

What is ActionMailer?

ActionMailer is the most popular gem if you need to deliver email in a Ruby on Rails app. It lets you send emails using mailer classes and views.

Here’s how a simple email built with ActionMailer may look:

class TestMailer < ActionMailer::Base
  default from: 'test@sender.com'
  def simple_message(recipient)
    mail(
      to: test@recipient.com,
      subject: 'Subject of the message',
      body: 'Body text of the message'
    )
  end
end

Create and send emails with ActionMailer

It’s unlikely that you’ll only be sending simple messages. In most cases, your Ruby app will send transactional emails and they will need to be refined. So, let’s go through each step to create an advanced message and send it using the SMTP server.

Step 1: Creating a mailer model

Let’s start with creating a mailer model because your app will use it to send emails:

$ rails generate mailer Notifier

You’ll also need helpers to generate an electronic message. They are defined in the mailer model. You can set up variables in the mailer views, options like :to address, and so on. Here are some helpers you can make use of:

  • attachments['filename.png'] = File.read('path/to/attachment.pdf') - to add attachments
  • attachments.inline['filename.png'] = File.read('path/to/attachment.pdf') - to add an inline attachment
  • headers['X-No-Spam'] = 'True' - to specify a header field
  • headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'}) - to specify multiple headers
  • mail - to specify the email to be sent

Here is an example, we’ve tailored:

class UserMailer< ApplicationMailer
  def simple_message(recipient)
    attachments["attachment.png"] = File.read("path/to/attachment.png")
    mail(
      to: “test@recipient.com”,
      subject: "Subject of the message",
      content_type: "text/html",
      body: "<html><h2>HTML body text</h2></html>"
    )
  end

In this mailer class, we have HTML text, as well as an attached PNG file. Now, we can create a corresponding view.

Step 2: Creating a mailer view

View is a template to be used with the mailer. You need to create an .erb file in app/views/notifier_mailer/. Name it similarly to the method in the mailer class. In our example, the name is new-account.html.erb. This template will be used for the HTML formatted emails. Also, you can make a text part for the email. For this, create a new-account.txt.erb file in the same directory. The content for both files is up to you.

Step 3: Configuring the server

Now, we can start configuring ActionMailer. SMTP is a default delivery method. You can adjust it using config.action_mailer.smtp_settings. Other delivery methods are sendmail, file (save emails to files), and test (save emails to ActionMailer::Base.deliveries array).

We’re interested in SMTP, so let’s configure it as follows:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:              'smtp.server.com',
  port:                 25,
  domain:               'example.com',
  user_name:            '<username>',
  password:             '<password>',
  authentication:       'login',
  enable_starttls_auto: true 
}

We use the port 25 as it’s set by default. Also, we picked Login as the authentication mechanism. Today, it’s a regular practice to use cloud-based delivery platforms like SendGrid. In this case, your server configuration will look as follows:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address   => 'smtp.sendgrid.net',
  :port      => 587,
  :domain    => 'sendgrid.com',
  :user_name => '<username>',
  :password  => '<password>',
  :authentication => 'plain',
  :enable_starttls_auto => true 
}

Step 4: Sending email to one or multiple recipients

After these steps, we’re ready to send the email. If you want to do this right away, call deliver_now. Accordingly, you need to call deliver_later to defer the delivery for later.

This is how it looks in practice:

UserMailer.simple_message('test@recipient.com').deliver_now

For multiple recipients, you can simply specify a list of email addresses. This can be done for the :to key, :cc key, or :bcc key. The list can be specified in the form of an array or a single string with email addresses separated by commas.

Wrapping up

So, do you think that ActionMailer is the best option to send email from your Ruby app? Some people don’t and prefer other gems like Ruby Mail or even the traditional way using Net::SMTP. Anyway, we hope that this text was useful and you haven’t wasted your time. Good luck in your endeavors!

Andriy is a Growth Manager at Mailtrap, a product that helps people inspect and debug emails before sending them to real users. He has over 5 years of experience in the field of marketing & product. Andriy loves to network with people. Running is his hobby and he enjoys discovering new places. You can connect with Andriy via Linkedin or Facebook.

Have a project that needs help?