This post contains a beginners guide to using Action Mailer to send emails from a Rails app.
My latest project for Flatiron school is The Carpool App - one central place for parents to post and find carpools for their kids. A big part of parents arranging carpools includes parents communicating with each other, especially to request for their child to join a carpool, and then for the driver of the carpool to either accept or reject the join request. As parents are not expected to keep their eyes glued to the website to see the updates, it became necessary to have the parents updated by sending them an email.
As my project is built on Rails, Action Mailer was the simplest, built in choice to use to send emails. As Action Mailer is not part of the curriculum at Flatiron, it meant that I needed to teach this bit of technology to myself. At first I was confused about how to implement Action Mailer, but once I got it figured out, and that first email came through, I recognized a familiar "railsy" approach that emphasizes naming conventions and a configuration similar to the MVC pattern (model, view, controller).
Let's get started!
- Generate a mailer
rails g mailer MailerName
Generating a mailer is the simplest way to get started as Rails will generate the following files:
app/mailers/mailer_name_mailer.rb
app/views/mailer_name_mailer
test files in both spec/mailers/mailer_name_spec.rb and
spec/mailers/previews/mailer_name_preview.rb
- Decide the default email address
All of the mailers inherit from ApplicationMailer. If all of the emails in your app will be coming from the same email address, you can set the default email in one location, in the ApplicationMailer.
class ApplicationMailer < ActionMailer::Base
default from: 'example@gmail.com'
layout 'mailer'
end
You will probably want to open up a new email account with your app name in it to send out app related emails.
- Add an Email Action to the Mailer
The next step is actually deciding what email you would like to send. For example, if you would like to send an email welcoming a new user to the app, you can create a welcome email. This would simply be a method in you mailer, defining the name of the email, what parameters are being passed in, where the email should be sent, and the subject of the email.
def welcome_email(user)
@user = user
mail(to: @user.email, subject: 'Welcome to The Carpool App')
end
- Creating a View
After defining the email, it is time to decide what the email should look like. What will the email say? This is determined in by creating a new file in app/views/mailer_name_mailer called welcome_email.html.erb
. It is important to note two things. Firstly, the name of the file must be in the folder named after your mailer. Secondly, the file must follow the naming conventions of being called the same name as your email method. This sticks to a Rails principle of convention over configuration, meaning that by following conventions there is a lot less work required to configure the different files.
Note: This file is an html.erb file, which is an html file with ruby embedded within.
Once you have created the file, copy and paste the following inside.
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1>Welcome to The Carpool App!</h1>
<p>Thanks for joining and have a great day!</p>
</body>
</html>
You can edit or add any other information inside the email. Using interpolation you could personalize the email with the user's name.
<h1>Welcome to The Carpool App, <%= @user.name %>!</h1>
... or add a link to bring the user back to your app ...
<a href="<%= @url %>" target="_blank">Click Here!</a>
- Call the Email Method in a Controller
Now that you have figured out exactly what the email should look like and what it should say, you need to call the email method. The best place to do this is in a controller action. As my example is an email sent when a new user signs up for an account, I will call the email method in my create action of the Users Controller.
class UsersController < ApplicationController
skip_before_action :authorize, only: [:create]
def create
user = User.create!(user_params)
session[:user_id] = user.id
if user
MailerNameMailer.welcome_email(user).deliver_now
end
render json: user, status: :created
rescue ActiveRecord::RecordInvalid => e
render json: { errors: e.record.errors.full_messages }, status: :unprocessable_entity
end
end
- Config
To ensure that everything will work correctly, copy and paste the following into your config/environments/development.rb file.
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.perform_deliveries = true
If you choose to have your emails sent from a gmail account, you will need to include the following.
config.action_mailer.default_options = {from: 'example@gmail.com'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
user_name: 'example',
password: 'password',
authentication: 'plain',
enable_starttls_auto: true }
I had some trouble with gmail allowing me to sign in from my app, and so I had to go into my new gmail account, enable two step verfication, and then create an app specific password to include above.
Another great option is to use the letter opener gem. This is a great tool to use in development, because instead of the app actually sending the email, instead it opens a new tab on your browser with the email view. This is really helpful to see what is going on with the email as it happens. If you are using the letter opener gem, you would need to install it:
gem install letter_opener -v 1.4.1
and include it in your config/environments/development.rb file.
config.action_mailer.delivery_method = :letter_opener
And that is it! You are now ready to send an email from your Rails app!
Top comments (0)