はじめに
Rails 6 に追加されそうな新機能を試す第27段。 今回は、 perform_deliveries
編です。
perform_deliveries
の値が false(nil) のとき、log への出力メッセージがメールの送信をスキップしたことを示す内容に変わりました。
今回は、User を登録するときに perform_deliveries
の値を画面から指定できるようにする(メールを送信する、しないを指定できるようにする)ことにより、動作を確認します。
Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease
でインストールできます。
$ rails --version
Rails 6.0.0.rc1
Rails プロジェクトを作る
$ rails new rails6_0_0rc1
$ cd rails6_0_0rc1
User の CRUD を作る
User の CRUD を作ります。
$ rails g scaffold User name
UserMailer を作る
メールを送信できるように、UserMailer を作ります。
$ rails g mailer UserMailer
View を変更する
_form.html.erb
に perform_deliveries
を true にするか false にするか指定するチェックボックスを追加します。
<%= form_with(model: user, local: true) do |form| %>
...
<div class="field">
<%= label_tag :perform_deliveries %>
<%= check_box_tag :perform_deliveries %>
</div>
...
<% end %>
User controller を変更する
UsersController#create
メソッドを変更し、DBへの保存が成功したら、 メールを送信するようにします。
このとき、perform_deliveries
の値をパラメータとして UserMailer
に渡すようにします。
class UsersController < ApplicationController
...
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
perform_deliveries = params[:perform_deliveries].to_i == 1
UserMailer.with(user: @user, perform_deliveries: perform_deliveries).created_email.deliver_later
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
...
end
以下の2行が追加した部分になります。
perform_deliveries = params[:perform_deliveries].to_i == 1
UserMailer.with(user: @user, perform_deliveries: perform_deliveries).created_email.deliver_later
このあとは、 UserMailer
側を修正していきます。
UserMailer クラスにメソッドを追加する
メールを送信する created_email
メソッド と perform_deliveries
を設定するコールバックを追加します。
class UserMailer < ApplicationMailer
after_action :set_perform_deliveries
def created_email
@user = params[:user]
mail(to: 'admin@example.com', subject: 'user created')
end
private
def set_perform_deliveries
mail.perform_deliveries = params[:perform_deliveries]
end
end
メールのテンプレートを作成する
今回は手抜きで テキストメールのみとし、 HTML メールは作成しません。
User created
=============
User <%= @user.name %> was created
メールをファイルに保存する
今回は実際にメールを送信せず、ファイルに保存するように設定を変更します。
Rails.application.configure do
...
config.action_mailer.delivery_method = :file
...
end
db:migrate を実行する
$ bin/rails db:create db:migrate
rails server を実行してブラウザからUserを登録する
User を登録するときに、 perform_deliveries
チェックボックスをチェックします。
ユーザーが無事、登録できれば、メールは、tmp/mails ディレクトリ内に保存されます。
このときログを確認すると
... Delivered mail 5ce9f3619b8f4_2f32ae97743a3b0258ac@8baf8e28fbad.mail (6.1ms)
とメールが送信されたことが記録されています。
今度は、perform_deliveries
チェックボックスをチェックしないで User を登録します。
tmp/mails ディレクトリの admin@example.com ファイルには何も追加されません。
このときログを確認すると Delivered
とはならずに
... Skipped delivery of mail 5ce9f380b1ad6_2f32ae97743a3b025957@8baf8e28fbad.mail as `perform_deliveries` is false
とメールの送信をスキップしたことがログに記録されます。 (←これが今回のちょい足し機能です。)
試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try027_perform_deliveries