Mailer specs are a great to verify that the emails sent from your Rails applications have the required data, links, and important content. But often a developer, or more likely the product owner, may want to see the emails to make sure they are properly formatted, read well, and are free of spelling errors.
Getting your application to send an email from a development or staging environment can be an onerous task depending on how much user workflow and data setup is required for a given email. This is where the mail_view gem can really help you out.
The mail_view gem lets us easily preview emails right from within your Rails application running in the development environment
Using mail_view in Rails 4.1+
mail_view is built into Rails 4.1+, so there is no additional setup or configuration to start using it.
You can read more about support for mail_view in Rails 4.1 in the following links
Setting up emails to preview
By default, Rails 4.1 expects the mail preview classes to be located in the test/mailers/previews directory. If you use the mail generator, a preview file will be created for you automatically. You create a class that inherits from ActionMailer::Preview for each email to be previewed.
class WelcomeMailerPreview < ActionMailer::Preview def welcome_investor user = User.last WelcomeMailer.welcome_investor(user) end end
Previewing the emails
Browsing to http://localhost:3000/rails/mailers/welcome_mailer/welcome_investor will show you a preview of the email. But before you do that you will probably need to set up some data for the preview
Using mail_view in Rails prior to 4.1
For Rails versions prior to 4.1, there is just a little work to do to get set up.
First you will need to add the gem to your Gemfile.
gem "mail_view", "~> 2.0.4"
Then you mount the mail_view engine into your application via the routes.rb file.
if Rails.env.development? mount MailPreview => 'mail_view' end
I wanted to make the mail_view available on my staging server, so I used an environment variable to enable it.
if Rails.env.development? || ENV["PREVIEW_EMAIL"] == "true" mount MailPreview => 'mail_view' end
With the engine mounted at mail_view, browsing to http://localhost:3000/mail_view will present us with a list of emails to preview. But before we do that, we need to set up the emails to preview.
Setting up emails to preview
You set up the emails to preview by creating a class that inherits from MailView
class MailPreview < MailView def welcome user = User.last WelcomeMailer.welcome_investor(user) end def payment_confirmation payment = Payment.last PaymentConfirmationMailer.confirmation_email(payment) end def contact_us ContactMailer.contact_email("Joe Smith", "617-555-1212", "email@example.com", "I have a question...") end
Listing the emails
Now that we have some emails to preview, we can browse to http://localhost:3000/mail_view will present us with a list of email preview links as defined in the MailPreview class.
Providing data for the emails
Typically our emails are working with data from our database. The mail_view documentation describes some of the ways you can provide data to the mailer, using either actual data from the database, using a factory pattern, or providing a stub.
In the examples above, I am using data from the database. Each approach has its advantages and disadvantages, and it really depends on how you data is structured as to which approach you use. You can also mix and match the different approaches as you see fit.
Viewing an email
mail_view displays a preview of the email with the header information shown in the page header and the body in an iframe, as shown below.
If you have provided a text and html template for the email, a drop-down is displayed in the page header to allow you to preview the different formats. Here we are displaying the text version of the email
Since the body of the email is displayed in an iframe, clicking on a link in the email will open the link inside the iframe.
The mail_view gem is a great tool to allow you to visually inspect the emails sent by your Rails application.
This is a great solution to business / technical problem I’ve had at almost every job in the last 10 years. Well done Mike.