Mar 02, 2016
Table of contents:
Sending emails is one of those aspects of building web applications that is totally necessary, but nevertheless, a pain in the arse.
There is so much value in sending emails that you can’t just not do it, yet there’s nothing fun about doing it.
As you could probably guess, sending email is such a core component of a web application that Rails has already got you covered.
Action Mailer is Rails’ abstraction for sending emails. This includes generating the markup, queuing the job, and sending the email.
In today’s tutorial we will be looking at using Action Mailer in Ruby on Rails.
A good way of thinking about how Action Mailer works is that it is similar to Controllers and Views in a normal web request.
The Mailer is similar to the Controller in that it accepts the request, sets things up and then ultimately returns the response.
You also have a View that is where you will write the markup for your email.
And of course you have tests for your mailers as it’s just as important to test them as it is to test Controllers.
Action Mailer is also an abstraction over the actual functionality of sending the email. This means you can switch providers without disrupting the code you have written by simply making a configuration change.
So the first thing we need to do is to create a new Mailer. To do this we can use the Rails generator:
bin/rails generate mailer UserMailer
create app/mailers/user_mailer.rb
create app/mailers/application_mailer.rb
invoke erb
create app/views/user_mailer
create app/views/layouts/mailer.text.erb
create app/views/layouts/mailer.html.erb
invoke test_unit
create test/mailers/user_mailer_test.rb
create test/mailers/previews/user_mailer_preview.rb
As you can see from the output above, this will create a number of files for you.
First we have the ApplicationMailer
class:
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
This class sets some default values and it will be used to as a parent class to extend each child Mailer class.
Next we have the UserMailer
itself:
class UserMailer < ApplicationMailer
end
This is like your Controller, so it’s here where you define the methods that accept the request to send an email.
Finally we have the various view and test files we will need but aren’t that important right now.
Firstly, we can create the first email method on the UserMailer
class:
class UserMailer < ApplicationMailer
def sign_up_confirmation(user)
@user = user
@url = # generate confirmation url
mail(to: @user.email, subject: 'Confirm your Culttt Membership!')
end
end
The first email I have defined is for sending a sign up confirmation when a new user registers with Culttt.
As you can see I’m passing in the User
from the code that is calling this method. Typically this will be part of the user on-boarding flow, just after the User
object was created by Active Record.
I’m also setting the User
and the generated url to be instance variables on the Mailer. In just the same way that instance variables from Controllers are available in Views, these instances variables will be available in my Mailer Views.
And finally I’m calling the mail
method and specifying the to
and subject
.
Now if you tried to run this Mailer you would get an error. Rails is expecting that the View is available, but we haven’t created it yet.
By default, Rails will expect that there is a sign_up_confirmation.html.erb
and a sign_up_confirmation.text.erb
file under the app/views/user_mailer
directory.
So in order to make it work we need to create those files and add the body of the email.
Now if you were to try to send the email again, it should work (well only if you have set up the configuration details too)
UserMailer.sign_up_confirmation(user).deliver_later
The final step to setting up Action Mailer is to configure your sending options. This will depend on how you want to send the email in your web application.
I usually go for a hosted email provider such as Mandrill or SendGrid, but the choice is up to you.
To set the Action Mailer configuration options, simply open up the files under config/environments
and add the appropriate configuration details for each environment.
For specific details to include I would look at your provider’s documentation.
And don’t store sensitive details in here, use environment variables instead!
The ability to send emails is something that just about every web application will require.
It doesn’t really matter if you are building a consumer or business application, you’re going to need to send emails to your users as some point.
Rails is a framework that aims to deal with this kind of foundational functionality for you so you can get on with doing the work that is important to your application.
Instead of dealing with the headache of sending emails yourself, Rails relieves you of the burden with a set of tools to make it easy.