Rails7 Devise パスワードリセット機能

### はじめに
はじめまして、初学者からプログラミング学習中のErikaと申します🐣
今回個人開発をしていて、Devise導入済みのRailsアプリケーションでのパスワードリセット機能実装で手こずったので記録として残します。

:::note warn
この記事は初学者が執筆したものであり、誤りが含まれている可能性があります。もし誤りがあれば、コメントなどでご指摘いただけると助かります🙇‍♀️
:::

### 開発環境
Rails 7.1.3.3
ruby 3.2.2

### 前提条件
Deviseが導入済み
Userモデル作成済み
.env導入済み

### ルーティングの確認
コメントの部分を足します。
```ruby:routes.rb
Rails.application.routes.draw do
    devise_for :users, controllers: {
            sessions: 'users/sessions',
            registrations: 'users/registrations',
            omniauth_callbacks: "users/omniauth_callbacks",
            passwords: 'users/passwords' #ここが必要
          }
end
```

### モデルの確認
コメントの部分を足します。
```ruby:models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable #recoverableが必要
end
```

### メールアドレスの作成
開発用のメールアドレスを作成します。
今回はgmailを使用するので、まずは開発用のgmailとGoogleアカウントを作成してください。
その後、https://myaccount.google.com/　
上記リンクにアクセスし、2段階認証を有効にします。

### アプリパスワードを生成する
2段階認証が有効になったら、「アプリパスワード」を生成します。
https://myaccount.google.com/apppasswords
上記リンクから直接アクセスし、作成をしてください。
アプリ名にはパスワードを使用したいアプリ名やわかりやすい名前を設定してください。
16桁のパスワードが発行されるので、コピーしてください。

:::note warn
完了を押してしまうと再度確認することはできないのでご注意下さい。
完了を押してしまった場合は作り直してください。
:::

### 環境変数に設定する
生成されたアプリパスワードを環境変数に設定します。

```.env
MAILER_SENDER='your_email@gmail.com'　# ここに使用するメールアドレスを入力
MAILER_PASSWORD='generated_app_password'  # ここに生成したアプリパスワードを入力
```
### SMTP設定
config/environments/development.rb(開発環境の場合) や config/environments/production.rb(本番環境の場合) に下記を記載します。

```ruby:config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.gmail.com',
  port: 587,
  domain: 'localhost', 
  user_name: ENV['MAILER_SENDER'],
  password: ENV['MAILER_PASSWORD'],
  authentication: 'plain',
  enable_starttls_auto: true
}
```

```ruby:config/environments/production.rb
  config.action_mailer.default_url_options = { host: 'https://your.app.com/' } # 本番環境のURLを入れてください。
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    domain:               'your.app.com', #自分のアプリのドメイン
    user_name:            ENV['MAILER_SENDER'],
    password:             ENV['MAILER_PASSWORD'],
    authentication:       'plain',
    enable_starttls_auto: true 
  }
```

### Deviseのメール設定
Deviseの設定ファイル（config/initializers/devise.rb）で、メール送信者を設定します。

```config/initializers/devise.rb
Devise.setup do |config|
  config.mailer_sender = ENV['MAILER_SENDER']
end
```

### Devise mailerの設定

この内容はお好みで編集可能です。私はHelloの後に、UserのEmailではなくUsername属性を表示しています。

```erb:devise/mailer/reset_password_instructions.html.erb
<p>Hello <%= @resource.username %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_user_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
```

:::note alert
reset_password_tokenがないとそもそもパスワード編集画面にすら遷移できなくなってしまうので消さないように注意してください。
:::

以上です！
あとは、実際にGmailからメールが届くか、その後パスワードの再設定ができるかを試してみてください。開発環境の場合、メールが送信されているかどうかはログでも確認できます。

:::note warn
本番環境では、実装後に別でENVファイルの読み込みをする必要がありますのでお忘れなく！
:::

私はfly.ioを使用しているので、下記記事を参考に環境変数を読み込みました。
https://qiita.com/00000000/items/013ce7cbac014e49b3c4

読んでいただきありがとうございます！

### 参考にさせていただいた記事
https://qiita.com/4ma9147/items/fc3f9fcf36572596fdf1#%E7%92%B0%E5%A2%83%E8%A8%AD%E5%AE%9A

https://zenn.dev/airiin/articles/0031bb89130583

https://zenn.dev/yuna0960740/articles/12d33231b8a961