Skip to content

Ruby on Rails - Send Emails

Action Mailer is the Rails component responsible for sending and receiving emails. It allows you to create mailer classes that inherit from ApplicationMailer (which in turn inherits from ActionMailer::Base) to handle email delivery.

Let’s create a simple application, mail_sender_app, to demonstrate sending emails.

$ rails new mail_sender_app
$ cd mail_sender_app

Configuration for Action Mailer is typically done in environment-specific files (e.g., config/environments/development.rb, config/environments/production.rb).

  1. Set Delivery Method: In config/environments/development.rb, specify how emails should be delivered. For development, letter_opener_web is a great gem that opens sent emails in your browser. For production, you’d use :smtp or a service like SendGrid, Postmark, etc.
# Gemfile
gem 'letter_opener_web', group: :development
# Then run: $ bundle install
config/environments/development.rb
Rails.application.configure do
# ... other configurations ...
config.action_mailer.delivery_method = :letter_opener_web # For development
config.action_mailer.perform_deliveries = true # Ensure emails are actually sent
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # Important for links in emails
end
  1. SMTP Settings (for production or if using SMTP in development): If using SMTP, configure settings like address, port, domain, username, and password. Never hardcode credentials; use Rails credentials or environment variables.
# config/environments/production.rb (example for Gmail SMTP - use with caution, app passwords recommended)
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'yourdomain.com', # Or your app's domain
user_name: ENV['GMAIL_USERNAME'],
password: ENV['GMAIL_APP_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true
}

Use the Rails generator to create a mailer. Let’s create a UserMailer with a welcome_email action:

$ bin/rails generate mailer UserMailer welcome_email

This creates app/mailers/user_mailer.rb and view templates in app/views/user_mailer/.

Edit app/mailers/user_mailer.rb:

class UserMailer < ApplicationMailer
default from: 'notifications@example.com' # Default sender address
def welcome_email(user)
@user = user
@url = 'http://example.com/login' # Example URL for the email
mail(to: @user.email, subject: 'Welcome to Our Awesome Site!')
# Rails will look for templates in app/views/user_mailer/welcome_email.html.erb and .text.erb
end
end
  • default from: sets a default sender for all emails from this mailer.
  • In welcome_email(user), @user makes the user object available to the view templates.
  • mail(to: ..., subject: ...) sends the email. Rails automatically creates multipart emails if both HTML and text templates exist.
  1. HTML Template (app/views/user_mailer/welcome_email.html.erb):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
</head>
<body>
<h1>Welcome to example.com, <%= @user.name %>!</h1>
<p>
You have successfully signed up to example.com, your username is: <%= @user.login %>.<br>
</p>
<p>
To login to the site, just follow this link: <%= link_to 'Login', @url %>.
</p>
<p>Thanks for joining and have a great day!</p>
</body>
</html>
  1. Text Template (app/views/user_mailer/welcome_email.text.erb):
Welcome to example.com, <%= @user.name %>!
===============================================
You have successfully signed up to example.com,
your username is: <%= @user.login %>.
To login to the site, just follow this link: <%= @url %>
Thanks for joining and have a great day!

You’ll typically send emails from your controllers or background jobs after certain events (e.g., user registration).

First, let’s set up a simple User model and controller:

$ bin/rails generate scaffold User name:string email:string login:string
$ bin/rails db:migrate

Modify the create action in app/controllers/users_controller.rb to send the welcome email:

class UsersController < ApplicationController
# ... other actions (index, new, show, edit, update, destroy) ...
# POST /users
def create
@user = User.new(user_params)
if @user.save
# Tell the UserMailer to send a welcome email after save
# .deliver_later sends email asynchronously using Active Job (recommended)
UserMailer.welcome_email(@user).deliver_later
redirect_to @user, notice: 'User was successfully created. Check your email!'
else
render :new, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :email, :login)
end
end
  1. Start your Rails server: $ bin/rails s
  2. If using letter_opener_web, navigate to http://localhost:3000/letter_opener in your browser.
  3. Navigate to http://localhost:3000/users/new to create a new user.
  4. Fill in the form and submit. If successful, the email should be “sent”.
  5. Check letter_opener_web (or your configured email delivery system) to see the email.

The log file (log/development.log) will also show details of the email being sent:

Rendering user_mailer/welcome_email.html.erb within layouts/mailer
Rendered user_mailer/welcome_email.html.erb within layouts/mailer (Duration: X.Xms)
Rendering user_mailer/welcome_email.text.erb within layouts/mailer
Rendered user_mailer/welcome_email.text.erb within layouts/mailer (Duration: X.Xms)
UserMailer#welcome_email: processed outbound mail in XXX.Xms
Sent mail to user@example.com (XXX.Xms)
[ActiveJob] Enqueued ActionMailer::MailDeliveryJob (Job ID: xxxxx) to SendGrid(mail)
...

Further Information: For advanced topics like attachments, inline images, and mailer testing, refer to the official Action Mailer Basics Guide.