今回はAction Mailerを使ったことがない人向けにチュートリアルを書いていきます。この記事はパーフェクトRuby on Railsを参考にさせていただきました。さらに詳細なことが知りたい場合、この本に丁寧に説明されています。ぜひ読んでみてください。
Action Mailerの機能を実装
まずはscaffoldで元となるアプリを作っていきます。
$ rails new action_mailer_tutorial
$ cd action_mailer_tutorial
$ bin/rails g scaffold user name email
$ bin/rails db:create
$ bin/rails db:migrate
Action Mailerで使うファイルをmailerのサブコマンドで生成します。
bin/rails g mailer UserMailer
メール送信時は先程生成したUserMailerクラスから送信します。メイラークラスの設計はコントローラーと似ていて、次のような特徴を持っています。
- paramsオブジェクトを経由して渡されたデータを取得する
- メイラークラスのメソッド内で処理した内容をインスタンス変数に代入してビューへ渡す
コントローラにおけるApplicationControllerに相当するメイラークラスが継承しているクラスがApplicationMailerで、そのファイルがapp/mailers/application/mailer.rbにあります。これを編集します。
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com' # ここで指定したアドレスからメールが送信される
layout 'mailer'
end
次にUserMailerクラスにメール送信処理を実装します。@nameにparamsで送られてくるnameがセットされ、params[:to]宛にメールを送信します。
class UserMailer < ApplicationMailer
def welcome
@name = params[:name]
mail(to: params[:to], subject: "登録完了")
end
end
次にViewを作っていきます。Action Mailerでは、mailメソッドを呼び出すとHTMLとテキストの2種類のテンプレートを探して、multipart/alternative形式のメールを作成します。これはHTMLとテキストの両方のフォーマットを持ったメールを送信し、受信側でフォーマットを選択する形式です。
<p><%= @name %>様</p>
<p>ユーザ登録完了!</p>
<%= @name %>様
ユーザ登録完了!
次にメーラーを使ってメールを送信する機能を実装します。ここでは、ユーザ登録が成功したらメールを送信するようにします。
respond_to do |format|
if @user.save
UserMailer.with(to: @user.email, name: @user.name).welcome.deliver_now
format.html { redirect_to @user, notice: "User was successfully created." }
format.json { render :show, status: :created, location: @user }
UserMailerクラスのwelcomeメソッドを実行します。withメソッドを使うことでparamsを一緒に送ることができます。((注)場所に注意です。) また、deliver_nowで同期的にwelcomeメソッドを実行しています。deliver_laterを使うと非同期に送ることも可能ですが、ここでは割愛します。
次にメールを送信する設定を行っていきます。開発環境ではメールをファイルとして保存する形式をとります。(実際にメールは送信されず、送信命令があったときに宛先ごとにファイルを作成し保存します。)
Rails.application.configure do
config.action_mailer.delivery_method = :file
# デフォルトではtmp/mails以下に保存される
# 略
end
これで、rails sでサーバーを起動してhttp://localhost:3000/usersにアクセスし、ユーザーを作成してみてください。tmp/mails以下にメールが作られているのが確認できるはずです。

Date: Tue, 16 Mar 2021 08:14:47 +0900
From: from@example.com
To: test@example.com
これで、一通りAction Mailerを使う準備ができました。
メール送信設定
次に実際にメール送信する設定を行います。ここでは、SMTPサーバとしてSendGridを利用します。(無料で使えます)
SendGridのアカウントを登録して、ユーザ名とパスワードをcredentialsを使って保存します。
$ bin/rails credentials:edit
はじめて開こうとするとこのような画面になるかと思います。
No $EDITOR to open file in. Assign one like this:
EDITOR="mate --wait" bin/rails credentials:edit
For editors that fork and exit immediately, it's important to pass a wait flag,
otherwise the credentials will be saved immediately with no chance to edit.
エディターを登録してくださいと言われているので登録します。ここではVimを使います。
$ EDITOR="vim" bin/rails credentials:edit
エディターが立ち上がるので、SendGridのユーザ名とパスワードを登録していきましょう。escして:wqとすれば保存できます。
# 略
smtp_user_name: ***************
smtp_password: **************
次にSMTP接続する設定を行います。
Rails.application.configure do
config.action_mailer.smtp_settings = {
user_name: Rails.application.credentials.smtp_user_name,
password: Rails.application.credentials.smtp_password,
domain: 'from@example.com',
address: 'smtp.sendgrid.net',
port: 587,
authentication: :plain,
enable_starttls_auto: true
}
end
また、次の設定をコメントアウトしておいてください。
# config.action_mailer.delivery_method = :file
これで、ユーザ登録後メールが届いているはずです。

Action MailerをRSpecでテストする
まずは、RSpecが使えるよう準備します。
$ bin/rails g rspec:mailer UserMailer
次に設定を行います。この設定を行うことで、テストを行う際に実際のメール送信は行わず、ActionMailer::Base.deliveries配列へ送信されたメールが格納されます。
Rails.application.configure do
config.action_mailer.delivery_method = :test
# 略
end
それではテストを書いていきます。長くなりましたが、難しいことはしてません。まずはUserMailerクラスからwelcomeメソッドを実行します。そうすると、上に書いた設定により、メールが配列となってActionMailer::Base.deliveries
に入るので、それを取り出して中身を確認しています。
require "rails_helper"
RSpec.describe UserMailer, type: :mailer do
describe 'send_mail' do
it '指定したアドレスからメールが送信されていること' do
UserMailer.with(name: 'さかい', to: "to@example.com").welcome.deliver_now
expect(ActionMailer::Base.deliveries.last.from.first).to eq ('from@example.com')
end
it '指定した送信先のアドレスであること' do
UserMailer.with(name: 'さかい', to: "to@example.com").welcome.deliver_now
expect(ActionMailer::Base.deliveries.last.to.first).to eq ('to@example.com')
end
it '正常にメールが送信されていること' do
UserMailer.with(name: 'さかい', to: "to@example.com").welcome.deliver_now
expect(ActionMailer::Base.deliveries.last.subject).to eq ('登録完了')
end
# DRYに書くと・・
subject(:mail) do
described_class.with(name: 'さかい', to: "to@example.com").welcome.deliver_now
ActionMailer::Base.deliveries.last
end
context 'when send_mail' do
it { expect(mail.from.first).to eq('from@example.com') }
it { expect(mail.to.first).to eq('to@example.com') }
it { expect(mail.subject).to eq('登録完了') }
end
end
end
きちんとテストがパスすれば成功です。
$ bin/rspec
まとめ
少し長くなりましたが、お疲れさまでした。これでAction Mailerについてざっくり分かったのではないでしょうか。僕自身、実務で使ったことがないので使い次第分かったことなどを共有できればと思います。
GitHubにレポジトリを上げておくので、詰まった人はこちらを参考にしてみてください。
ここまで読んでくださりありがとうございました。