Introduction

In the past we've had to resort to cumbersome workarounds in order to preview/modify our mailers in Ruby on Rails. Luckily, this has changed with the introduction of Ruby on Rails 4.1 Action Mailer Previews. Action Mailer Previews let you quickly and easily preview emails from within your browser. In this article we will cover the basics of using Action Mailer Previews.

Rails Application Setup

Heads Up! Make sure you generate an application using Rails 4.1. Simply do a 'gem update rails' and it should update you to 4.1. Run 'rails --version' to ensure you in fact are running Rails 4.1.

In order for us to play with Action Mailer Previews we need to first create a few different things. First, we need to create a model. In this example we will create a model called User, which will store User information. We will also add some seed data to play with as well as a mailer called UserMailer. Creating a mailer with the rails g mailer command will automatically generate the code necessary for our mailer preview.

First let's create the user model. Open up a terminal and run the code listed below.

Terminal Commands:

rails g model User email:string  first_name:string last_name:string
rake db:migrate

Great, now lets add some seed data. Open up your seeds file and add in the code listed below.

db/seeds.rb:

User.delete_all
User.create!({ id: 1, email: "salliesue@mailinator.com", first_name: "Sallie", last_name: "Sue" })
User.create!({ id: 2, email: "bsmith222@mailinator.com", first_name: "Bob", last_name: "Smith" })
User.create!({ id: 3, email: "jdoe630@mailinator.com", first_name: "John", last_name: "Doe" })
User.create!({ id: 4, email: "rich2281@mailinator.com", first_name: "Rich", last_name: "Johnson" })
User.create!({ id: 5, email: "jonwh2@mailinator.com", first_name: "Jon", last_name: "White" })

Now lets run db:seed to add the seed data to our database.

Terminal Commands:

rake db:seed

Great, now lets generate our mailer. Run the code listed below to generate the user mailer.

Terminal Commands:

rails g mailer UserMailer new_user

Great, now lets edit our User mailer preview and add some code to make our email preview work. Open up your UserMailer preview and modify it so that it looks like the code listed below.

test/mailers/previews/user_mailer_preview.rb:


class UserMailerPreview < ActionMailer::Preview

  def new_user
    user = User.first
    UserMailer.new_user(user)
  end

end

Now let's modify our mailer. Open up the user mailer and modify it so that it looks like the code listed below.

app/mailers/user_mailer.rb:

class UserMailer < ActionMailer::Base
  default from: "from@example.com"

  def new_user(user)
    @user = user
    mail to: user.email, subject: "Hello!"
  end
end

Next let's make our mailer output something. First open up the html mail view and add in the code listed below.

app/views/user_mailer/new_user.html.erb:

<h1>Hello <%= @user.first_name %>!</h1>

<p>
  Welcome to my website!
</p>

Now open up the text mail view and add in the code listed below.

app/views/user_mailer/new_user.text.erb:

Hello <%= "#{@user.first_name} #{@user.last_name}" %>!

Welcome to my website!

Great. now if we start a rails server and visit http://localhost:3000/rails/mailers/user_mailer/new_user we will see a preview of the html version of the mailer. Clicking the drop down will allow us to switch between both the html and text versions of the email.

Changing the Path

By default, mailer previews are stored in the test folder. This might be an issue if you don't have a test folder (for example, if you are using rspec). Fortunately you can easily change the path by setting config.action_mailer.preview_path in development.rb. It's wise to avoid placing the mailer previews in the app folder however, since this gets eager loaded on production.

Known Caveats

  • It does not appear to be easily possible to view an email destined for a specific user without hard coding it in the preview.
  • The top portion of the email with the drop down appears to get loaded separately from the bottom portion. This means if you grab a random user, the email address listed in the to: field at the top may be different from the one in the body of the email.

That's it, thanks for reading!