Skip to content

Ror Mailers

DodaTech 4 min read

title: Ruby on Rails Mailers — Complete Guide to Action Mailer description: 'Learn Ruby on Rails Action Mailer: sending emails, mailer generators, email previews, attachments, HTML and text templates, delivery methods, and background email delivery.' date: 2026-06-28 lastmod: 2026-06-28 weight: 28 tags: [backend, ror]


Rails Action Mailer provides a framework for sending emails using mailer classes and views, supporting HTML and plain text templates, attachments, and background delivery.

## What You'll Learn

By the end of this tutorial, you'll create mailers with generators, build HTML and text templates, add attachments, preview emails in development, configure delivery methods, and send emails in the background.

## Real-World Use

An e-commerce app sends order confirmations, shipping updates, password resets, and weekly newsletters. Users receive HTML emails with inline images and tracking pixels.

## Mailers Learning Path

```mermaid
flowchart LR
  A[Asset Pipeline] --> B[Mailers]
  B --> C[Background Jobs]
  C --> D[Caching]
  D --> E[Security]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

Generating a Mailer

rails generate mailer UserMailer welcome notification
# Creates:
# app/mailers/user_mailer.rb
# app/views/user_mailer/welcome.html.erb
# app/views/user_mailer/welcome.text.erb
# app/views/user_mailer/notification.html.erb
# app/views/user_mailer/notification.text.erb
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  default from: "noreply@myapp.com"

  def welcome(user)
    @user = user
    @login_url = new_user_session_url
    mail(to: @user.email, subject: "Welcome to MyApp!")
  end

  def notification(user, message)
    @user = user
    @message = message
    mail(to: @user.email, subject: "New notification")
  end
end

Email Templates

<!-- app/views/user_mailer/welcome.html.erb -->
<!DOCTYPE html>
<html>
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
</head>
<body>
  <h1>Welcome, <%= @user.name %>!</h1>
  <p>Thanks for joining MyApp. We're excited to have you on board.</p>
  <p><%= link_to "Get Started", @login_url %></p>
  <p>Best regards,<br>The MyApp Team</p>
</body>
</html>
<!-- app/views/user_mailer/welcome.text.erb -->
Welcome to MyApp, <%= @user.name %>!

Thanks for joining MyApp. We're excited to have you on board.

Get started: <%= @login_url %>

Best regards,
The MyApp Team

Sending Emails

# In controller
class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      UserMailer.welcome(@user).deliver_later  # Background
      redirect_to @user, notice: "Account created. Welcome email sent."
    else
      render :new, status: :unprocessable_entity
    end
  end
end

# Synchronous delivery (blocking)
UserMailer.notification(user, "Your order shipped").deliver_now

Email with Attachments

class InvoiceMailer < ApplicationMailer
  def send_invoice(user, invoice)
    @user = user
    @invoice = invoice
    attachments["invoice_#{invoice.id}.pdf"] = generate_pdf(invoice)
    attachments["receipt.pdf"] = File.read(Rails.root.join("tmp/receipt.pdf"))
    mail(to: @user.email, subject: "Invoice ##{invoice.id}")
  end

  private

  def generate_pdf(invoice)
    # Generate PDF content (e.g., with Prawn or WickedPdf)
    pdf = WickedPdf.new.pdf_from_string(
      render_to_string("invoices/pdf", layout: false)
    )
    pdf
  end
end

Configuration

# config/environments/development.rb
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }

# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "smtp.sendgrid.net",
  port: 587,
  domain: "myapp.com",
  user_name: Rails.application.credentials.sendgrid[:username],
  password: Rails.application.credentials.sendgrid[:password],
  authentication: "plain",
  enable_starttls_auto: true
}
config.action_mailer.default_url_options = { host: "myapp.com" }

Previewing Emails

# spec/mailers/previews/user_mailer_preview.rb
class UserMailerPreview < ActionMailer::Preview
  def welcome
    user = User.first || User.new(name: "Preview User", email: "preview@example.com")
    UserMailer.welcome(user)
  end

  def notification
    user = User.first || User.new(name: "Preview User", email: "preview@example.com")
    UserMailer.notification(user, "This is a test notification")
  end
end
# Visit http://localhost:3000/rails/mailers

Common Mistakes

1. Blocking Requests with Email

Sending email synchronously blocks the request. Use deliver_later with Active Job for background delivery.

2. Forgetting to Set default_url_options

Email templates use named routes. Without host configuration, URLs are malformed.

3. Not Testing Email Deliveries

Use ActionMailer::Base.deliveries in tests to verify emails are queued. Assert on subject and recipient.

4. Missing Text Templates

HTML-only emails look broken in text-only clients. Always provide .text.erb templates.

5. Hardcoding From Address

Set default from in ApplicationMailer. Override per mailer if needed.

Practice Questions

1. What is Action Mailer?

Rails' email framework. Mailers are like controllers with views, but generate emails instead of HTML pages.

2. How do you send an email in the background?

Use deliver_later instead of deliver_now. Requires Active Job backend (Sidekiq, SolidQueue).

3. How do you preview emails in development?

Create mailer previews in spec/mailers/previews/. Access at /rails/mailers.

4. What is the difference between .html.erb and .text.erb templates?

HTML for rich email clients. Text for plain text email clients (Outlook, Gmail text view).

5. Challenge: Create a mailer that sends an order confirmation with attachments.

class OrderMailer < ApplicationMailer
  def confirmation(order)
    @order = order
    @user = order.user
    attachments["order_#{order.id}.pdf"] = generate_invoice_pdf(order)
    mail(to: @user.email, subject: "Order ##{order.id} Confirmed")
  end
end

FAQ

What is letter_opener?

A development gem that opens emails in the browser instead of sending them. Great for testing email appearance.

How do I send emails with attachments?

Use attachments['filename.pdf'] = content in the mailer method.

What SMTP service should I use?

SendGrid, Mailgun, Amazon SES, and Postmark are popular. Configure in production.rb.

Can I send emails in bulk?

Use deliver_later with background jobs. Use multiple workers for high volume. Be aware of rate limits.

How do I track email opens?

Embed a tracking pixel (1x1 transparent image) with a unique URL. Use services like SendGrid for built-in analytics.

Mini Project: Welcome Mailer

Create a user welcome mailer with HTML and text templates, preview, and background delivery.

rails generate mailer UserMailer welcome
# Edit mailer, templates, and preview
# Configure letter_opener for development
UserMailer.welcome(user).deliver_later

What's Next

Ruby on Rails Background Jobs Ruby on Rails Caching

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro