【Rails Tutorial12章】パスワード再設定機能の実装手順を整理してみました【中編】

##はじめに
Railsチュートリアル12章の内容を、少しでも理解の助けとなればと思い、割としっかり目に整理しました！
__備忘録です。__
<br>
##前提
Railsチュートリアル１〜11章までの内容が完了していること。
特に、アカウント有効化機能が実装されている事。
<br>
##内容
Railsチュートリアル12章の__パスワード再設定機能の実装手順__を、前中後半の3回に分けて整理おります。
中編である今回は、__パスワード再設定メール送信機能の実装__を行っていきます！

前編→[__パスワード再設定用のリソース作成__](https://qiita.com/kurawo___D/items/44b36354f36bbe238d6b)
後編→[__パスワード再設定機能の本実装__]()
<br>
##2.パスワード再設定用メールを送信する機能を実装する。
　　➡︎PasswordResetsコントローラのcreateアクションを動作させる部分まで完成させたので、次はパスワード再設定に関するメールを送信する機能を実装していく。

　　➡︎今回はUserメイラーに追加されている、password_resetメソッドが追加されている事を前提に進めます。

####2-1.パスワード再設定用のメールとテンプレートを作成する。
　　➡︎前編で示した、UserMailerを使ってパスワードリセットのメールを送信するためのメソッドの中身を実装していく。
　　　　→UserMailer.password_reset(self).deliver_nowの中身。

　　__1.パスワード再設定用のリンクをメールで送信するメソッドを定義する。__
　　　　➡︎app/mailers/user_mailer.rbファイルへ移動する。
　　　　　　→password_reset(user)メソッドの中身を定義していく。
　　　　　　　　→取得したユーザーを@userインスタンス変数へ代入する処理を記述する。
　　　　　　　　→メールの宛先を取得したユーザーのメアドにして、件名も一緒に送信されるよう処理を記述する。

　　__2.パスワード再設定のテキストテンプレートを作成する。__
　　　　➡︎views/user_mailer/password_reset.text.erbファイルへ移動。
　　　　　　→ユーザーを取得した際に発行されたトークンと、ユーザーのメールアドレスを含んだPasswordResetsコントローラへのURLのリンクを表示させる。
　　　　　　　　→<%= edit_password_reset_url(@user.reset_token, email: @user.email) %>

　　__3.パスワード再設定用のHTMLテンプレートを作成する。__
　　　　➡︎views/user_mailer/password_reset.html.erbファイルへ移動する。
　　　　　　→ユーザーを取得した際に発行されたトークンと、ユーザーのメールアドレスを含んだPasswordResetsコントローラへのURLリンクを表示させる。
　　　　　　　　→<%= link_to "パスワードの再設定", edit_password_reset_url(@user.reset_token, email: @user.email) %>

　　__4.パスワード再設定のプレビューメソッドを定義し、可視化。__
　　　　➡︎test/mailers/previews/user_mailer_preview.rbファイルへ移動する。。
　　　　　　→メソッド名はpassword_reset。
　　　　　　　　→プレビューするためにDBから適当に最初のユーザーを取得する処理を記述。
　　　　　　　　→取得したユーザーの仮想トークンに、new_tokenメソッドを使ってランダム文字列を代入。
　　　　　　　　→UserMailerに対して、password_reset(user)メソッドを呼び出して、メールを送信させる処理を記述する。

　　　　➡︎これで、HTMLメールと、テキストメールをそれぞれプレビューできるようになる。
　　　　　　→注意すべきは、 development環境のメール設定において正しいhostが設定されているかを確認する事。

####2-2.パスワード再設定用のメイラーメソッドに対するテストを書いていく。
　　➡︎test/mailers/user_mailer_test.rbへ移動。
　　　　→パスワードリセット用のテストを定義する。
　　　　　　→テスト用のユーザーを変数へ代入。
　　　　　　→テスト用ユーザーの仮想トークンに、ランダムな文字列を代入する処理を記述する。
　　　　　　→メイラーを使って取得したユーザーのパスワード再設定用リンクをメールで送信するメソッドを呼び出し、変数へ代入。
　　　　　　→上記で取得したメールの件名と、実際に表示される件名が一致するかどうかを検証する記述を行う。
　　　　　　→上記で取得したメールの送信相手と、実際の送信相手が一致するかどうかを検証する記述。
　　　　　　→上記で取得したメールの送信元のアドレスが、実際に送信を行なっているアドレスと一致するかどうかを検証する記述。
　　　　　　→発行されたリセットトークンが、上記で取得したメール内に含まれているかどうかを検証する記述を行う。
　　　　　　→エスケープ処理後のユーザーのメールアドレスが、上記で取得したメールの内容に含まれているかどうかを検証する記述を行う。

　　　　➡︎テストスイートGREEN。

>```ruby:app/mailers/user_mailer.rb
  #2-1.1
  class UserMailer < ApplicationMailer
    @user = user
    mailer to: user.email, subject: "件名が入る"
  end
```

>```ruby:app/views/user_mailer/password_reset.text.erb
  #2-1.2
  以下のリンクをクリックして、パスワードの再設定を行ってください。
  <%= edit_password_reset_url(@user.reset_token, email: @user.email) %>
```

>```ruby:app/views/user_mailer/password_reset.html.erb
  #2-1.3
  <p>以下のリンクをクリックして、パスワードの再設定を行ってください。</p>
  <%= link_to "パスワードを再設定する", edit_password_reset_url(@user.reset_token, email: @user.email) %>
```

>```ruby:test/mailers/previews/user_mailer_preview.rb
  class UserMailerPreview < ActionMailer::Preview
    def password_reset
      user = User.first
      user.reset_token = User.new_token
      UserMailer.password_reset(user)
    end
  end
```

>```ruby:test/mailers/user_mailer_test.rb
  class UserMailerTest < ActionMailer::TestCase
    .
    .
    .
    test "password reset" do
      user = users(:michael)
      user.reset_token = User.new_token
      mail = UserMailer.password_reset(user)
      assert_equal "記述した件名", mail.subject
      assert_equal [user.email], mail.to
      assert_equal ["記述した送信元メアド"], mail.from
      assert_match user.reset_token, mail.body.encoded
      assert_match CGI.escape(user.email), mail.body.encoded
    end
  end
```

<br>
##最後に
　以上で中編の__パスワード再設定メール送信機能の実装__が完了しました。
　前編→[__パスワード再設定用のリソース作成__](https://qiita.com/kurawo___D/items/44b36354f36bbe238d6b)
　後編→[__パスワード再設定機能の本実装__]()

##参考
　[Railsチュートリアル 第12章パスワードの再設定](https://railstutorial.jp/chapters/password_reset?version=5.1#cha-password_reset)