Rails send email: How to send email in Ruby on Rails

Editorial Note: We may earn a commission when you visit links on our website.

Sending email in Ruby on Rails requires three things: ActionMailer configured per environment, a reliable SMTP provider, and background processing so emails don’t block response time.

Connecting Rails directly to Gmail or a generic SMTP server works fine in development, but is often flagged as spam in production.

After configuring ActionMailer across a dozen Rails apps, I’ve found that a dedicated transactional email provider eliminates the problem entirely.

This tutorial walks you through configuring ActionMailer with SendLayer’s SMTP, writing a mailer class, and delivering email in the background with Active Job.

How to send email in Ruby on Rails

Prerequisites

Before you begin, make sure you have:

  • Ruby 3.x and Rails 7.x or 8.x installed.
  • A Rails app (new or existing).
  • An email provider. Preferably, one that includes features like event tracking.

I’ll use SendLayer email provider for this tutorial, but the steps are similar regardless of the provider you use.

If you don’t have a SendLayer account yet, you can sign up for free and send up to 200 emails. One of the standout features I like about SendLayer is the domain reputation feature. Your emails are sent from a subdomain, which protects your actual domain in case of issues.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

How does email sending work in Rails?

Rails has a built-in module for email called ActionMailer. Think of it like a controller. It handles emails instead of web responses.

You create a mailer class with methods for each email type. Each method has a matching view template, just like a controller action has a view. When you call the method, Rails renders the template and sends it through your configured SMTP server.

How emails work in Ruby on Rails

The SMTP server is where your SMTP provider comes in. ActionMailer handles the structure. The SMTP provider, in this case, SendLayer, handles the delivery.

Step 1: Generate your mailer class

To get started, open a terminal window and run this command within your Rails project directory:

bin/rails generate mailer UserMailer

Rails creates 3 files:

create  app/mailers/user_mailer.rb
create  app/views/user_mailer/
create  test/mailers/user_mailer_test.rb

Open app/mailers/user_mailer.rb. It looks like this:

class UserMailer < ApplicationMailer
end

That’s our starting point. We’ll add email methods here in Step 2.

Pro Tip: ApplicationMailer inherits from ActionMailer::Base. You can set a default from: address in app/mailers/application_mailer.rb so every mailer uses the same sender address automatically.

Step 2: Create a mailer method and email view

Replace the contents of app/mailers/user_mailer.rb with the following:

class UserMailer < ApplicationMailer
  def welcome_email
    @user = params[:user]
    mail(to: @user.email, subject: 'Welcome to the app!')
  end
end

Now create the HTML view at app/views/user_mailer/welcome_email.html.erb:

<!DOCTYPE html>
<html>
  <body>
    <h1>Welcome, <%= @user.name %>!</h1>
    <p>Thanks for joining. Your account is ready.</p>
  </body>
</html>

Also create a plain-text fallback at app/views/user_mailer/welcome_email.text.erb:

Welcome, <%= @user.name %>!

Thanks for joining. Your account is ready.

Pro Tip: Always include a plain-text version. Some email clients don’t render HTML. Without .text.erb, those users see a blank email.

At this point, your mailer class and templates are ready. Next, we’ll connect them to the SMTP provider.

Step 3: Configure SMTP settings

Open config/environments/production.rb and add this block. Using a dedicated SMTP provider avoids common email deliverability issues that generic SMTP setups run into.

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:              'smtp.sendlayer.net',
  port:                 587,
  domain:               ENV['MAIL_DOMAIN'],
  user_name:            ENV['SMTP_USERNAME'],
  password:             ENV['SMTP_PASSWORD'],
  authentication:       :plain,
  enable_starttls_auto: true
}

For development testing, add the same block to config/environments/development.rb.

You’ll need to retrieve your SMTP credentials from the email provider you chose. In SendLayer, you’ll be able to access these details from your account area.

Once logged in, navigate to the Settings sidebar menu. Then select the SMTP Credentials tab.

SendLayer SMTP credentials

You’ll see the SMTP credentials required to use SendLayer’s SMTP server. The Host and Port number are the same for all users. However, the Username and Password details are unique to your SendLayer account.

Secure credentials with environment variables

Never hardcode your SMTP credentials in a config file. Use environment variables instead. I’ve seen exposed credentials get abused within hours of a leaked .env file.

Add these to your .env file (or set them in your hosting platform’s environment settings):

SMTP_USERNAME=your_sendlayer_smtp_username
SMTP_PASSWORD=your_sendlayer_smtp_password
[email protected]
MAIL_DOMAIN=yourdomain.com

Warning: Never commit .env to version control. Add it to .gitignore. Exposed credentials let anyone send email from your domain.

Step 4: Send email with Rails

With the mailer and SMTP config in place, you can trigger the email from a controller action. Here’s an example in a RegistrationsController:

class RegistrationsController < ApplicationController
  def create
    @user = User.new(user_params)

    if @user.save
      UserMailer.with(user: @user).welcome_email.deliver_now
      redirect_to root_path, notice: 'Account created!'
    else
      render :new
    end
  end
end

deliver_now sends the email immediately, before the response returns to the browser. It works fine for low-traffic apps. Step 5 covers a better approach for production.

To test it now, open the Rails console and trigger the email manually:

rails console

Then type the command below to create a test user.

user = User.create(email: "[email protected]", password: "123456")

Then send the email to the new user we created.

UserMailer.with(user: user).welcome_email.deliver_now

Check your SendLayer dashboard. You should see the email in your sent log within a few seconds.

If you have access to the email inbox, you should also receive the welcome email.

Send email in Ruby gmail example

Step 5: Send emails in the background with deliver_later

Sending email synchronously blocks your app. If SendLayer takes 200ms to accept the message, your user waits 200ms longer for their page to load. For high-traffic apps, that adds up fast.

Swap deliver_now for deliver_later:

UserMailer.with(user: @user).welcome_email.deliver_later

deliver_later queues the email using Active Job. Rails processes it in the background after the response is sent.

Rails 8 ships with Solid Queue built in. It runs background jobs using your existing database. No Redis, no Sidekiq, no extra infrastructure.

To use it, set the queue adapter in config/application.rb:

config.active_job.queue_adapter = :solid_queue

That’s all you need for Rails 8. For Rails 7, add Sidekiq or another Active Job backend. See the Rails Active Job guide for options.

Pro Tip: Use deliver_later in production and deliver_now in test and development. It keeps your test suite fast and your development feedback instant.

How to test your mailer without sending real emails

ActionMailer has a built-in preview feature. It renders your email in the browser without sending it.

Create a preview file at test/mailers/previews/user_mailer_preview.rb:

class UserMailerPreview < ActionMailer::Preview
  def welcome_email
    user = User.first
    UserMailer.with(user: user).welcome_email
  end
end

Visit http://localhost:3000/rails/mailers/user_mailer/welcome_email to see your email rendered live. Rails picks up previews from test/mailers/previews by default.

Browser showing actionmailer preview of welcome email at rails mailers path

For unit tests, ActionMailer stores sent emails in ActionMailer::Base.deliveries. Check it in your test suite:

assert_equal 1, ActionMailer::Base.deliveries.count
assert_equal ['[email protected]'], ActionMailer::Base.deliveries.last.to

Make sure your test environment uses the test delivery method. Add this to config/environments/test.rb if it isn’t already there:

config.action_mailer.delivery_method = :test

How do you troubleshoot common Rails email errors?

Most Rails email issues fall into 4 categories: authentication, deliverability, queuing, and template errors. Here’s how to fix each one.

Why am I getting Net::SMTPAuthenticationError?

Your SMTP credentials don’t match what the email provider expects. Check that SMTP_USERNAME and SMTP_PASSWORD are set and loading correctly. Run this in the Rails console to confirm:

puts ENV['SMTP_USERNAME']

If you’re on Heroku, Render, or a similar platform, set environment variables in the platform’s dashboard. This is because the .env isn’t read in production by default.

Why are my emails going to spam?

Emails sent through generic SMTP servers often land in spam because they lack proper SPF, DKIM, and DMARC records. SendLayer configures all 3 automatically when you send through smtp.sendlayer.net.

If emails still reach spam after switching to SendLayer, your domain’s DNS records may not be verified yet. In your SendLayer dashboard, go to Settings » Domains to confirm your domain is verified.

Why isn’t deliver_later sending my emails?

deliver_later enqueues a job — but if no queue worker is running, the job sits there permanently. In development, start Solid Queue with:

bin/rails jobs:work

In production, make sure your queue worker runs as a persistent process. You can confirm jobs are enqueued by checking the solid_queue_jobs table (Rails 8) or your Sidekiq dashboard (Rails 7).

Why am I getting ActionView::MissingTemplate?

Rails looks for a template named after the mailer method. If your method is welcome_email, Rails expects app/views/user_mailer/welcome_email.html.erb. A mismatch between the method name and the template filename raises this error. Rename one to match the other.

What are your options for sending email in Rails?

Rails gives you 3 ways to send email. SMTP is the most common. It works with any provider and requires no extra gems. An API approach is faster and more resilient for high-volume sending.

OptionHow it worksBest for
SMTPActionMailer connects to your provider’s SMTP serverMost apps. Simple setup, works with any provider
HTTP APISends via your provider’s REST API using a gemHigh-volume sending or when SMTP port 587 is blocked
Letter OpenerIntercepts emails and opens them in your browserDevelopment only — no real sending

This tutorial uses SMTP; it’s the fastest way to get started and works with SendLayer out of the box. If you need the API approach, SendLayer’s API docs cover the HTTP endpoint and authentication.

FAQs – Send email in Rails

Below, we’ve answered some of the top questions developers ask about sending emails in Ruby on Rails.

How can I set up a new Ruby on Rails application?

To set up a Rails app, you’ll first need to install Ruby on your machine. This provides access to the Ruby package manager (gem). With the package manager, run the command below to install Rails.

gem install rails

After that, use the command below to start a new project:

rails new my_app && cd my_app

In the command above, my_app is the project name. You can use any name you’d like for your project.

To start the server, run the command below:

bin/rails server

The server should start running on localhost:3000. Open your browser and navigate to this page. You should see a basic landing page.

Ruby on Rails app installed

What is ActionMailer in Ruby on Rails?

ActionMailer is Rails’ built-in email framework. It lets you create mailer classes with methods that generate emails, using ERB templates for the content. You configure it once with an SMTP provider, and it handles all your app’s outgoing email.

What’s the difference between deliver_now and deliver_later?

deliver_now sends the email immediately and blocks the current request until the email is sent. deliver_later queues the email as a background job and returns the response right away. Use deliver_later in production so emails don’t slow down page loads.

How do I test ActionMailer emails without sending real emails?

Use ActionMailer previews to view rendered emails in your browser during development. For automated tests, set config.action_mailer.delivery_method = :test and check ActionMailer::Base.deliveries to verify emails were queued correctly.

Can I use Gmail SMTP with Ruby on Rails?

Yes, but it’s not recommended for production. Gmail SMTP works in development, but Google limits regular accounts to 500 emails per day and flags bulk sending as spam.

To use it, set delivery_method to :smtp, use smtp.gmail.com on port 587, and use a Gmail App Password, not your regular password.

For production, a dedicated transactional email provider like SendLayer gives you higher limits, better deliverability, and SPF/DKIM records out of the box.

That’s it! Now you know how to send emails from your Ruby on Rails application.

You’ve set up ActionMailer, created a welcome email, connected it to SendLayer’s SMTP, and configured background sending with deliver_later. That’s a solid, production-ready email setup for your Rails app.

If you’re working with plain Ruby outside of Rails, check out our guide on sending emails in Ruby for a standalone approach.

  • 200 Free Emails
  • Easy Setup
  • 5 Star Support

Ready to send your emails in the fastest and most reliable way? Get started today with the most user-friendly and powerful SMTP email delivery service. SendLayer Business includes 5,000 emails a month with a longer log retention and premium support.