★ 完成イメージに対し、どういった実装をするのか必要なのかを洗い出しておくと。To doリストを作っておくことで、こんがらがってきたときに対処しやすい。
ユニーク制約、nilは許可する
bundle exec rails g sorcery:install reset_password --only-submodules
マイグレーションファイルにユニーク制約追加
add_index :users, :reset_password_token, unique: true
モデルにもバリデーション追加
この時、一意性を保つuniqueness: true
だけでなく、allow_nil: true
というオプションを追加すること。この記載がない場合、tokenがnilの時も重複と見なされてしまう。tokenはデフォルトではnilのため、複数のユーザーを登録できなくなってしまう。nilという状態を許容してあげる必要がある。
※wikiに書いていことはままある
validates :reset_password_token, uniqueness: true, allow_nil: true
password_resetsコントローラの働き
★ぼっち演算子、破壊的メソッドを使う理由
# password_resets_controller.rb def create @user = User.find_by(email: params[:email]) @user&.deliver_reset_password_instructions! # ここでぼっち演算子を用いているのは、emailが実在するしないに関わらず処理を通すため # 適当にメアドを打って、実在するかしないか確認できてしまうのはセキュリティ面でよろしくない # 失敗時の処理を指定していないため破壊的メソッドを使って、失敗時には例外を発生させる redirect_to login_path, success: 'パスワードリセット手順を送信しました' end
★edit,updateアクションでは@userが存在しなかった場合の処理が記載されているが、if文は後置ifを用いて短く書くことができる
def edit @token = params[:id] @user = User.load_from_reset_password_token(@token) # トークンからユーザーを検索する処理。wikiだと引数にparams[:id]を渡しているが、@tokenを渡しても同じことなのでどちらでも可 # 変更前 if @user.blank? not_authenticated return end # 変更後 return not_authenticated if @user.blank? end
def update @token = params[:id] @user = User.load_from_reset_password_token(@token) return not_authenticated if @user.blank? @user.password_confirmation = params[:user][:password] if @user.change_password(params[:user][:password]) redirect_to login_path, success: 'パスワードを変更しました' else flash.now[:danger] = 'パスワードを変更できませんでした' render :edit end end
サブモジュールの追加、メイラーの設定
# config/initializers/sorcery.rb # サブモジュールを追加する記載 Rails.application.config.sorcery.submodules = [:reset_password] Rails.application.config.sorcery.configure do |config| config.user_config do |user| # メイラーを指定する記載 # コメントアウトされているので、#を外せばOK user.reset_password_mailer = UserMailer end end
メール本文のtext形式、html形式は何が違うのか
reset_password_email.html.erb
とreset_password_email.text.erb
と二つ存在する理由について
まず、html形式の方が色をつけられたり、画像を挿入できたりバリエーションに富んだメールを送ることができる。けれどもブラウザによってはhtml形式のメールを表示することができないものもあるらしいので、そういったクライアントに対してメール本文が確認できるように、テキスト形式のものも用意しておく。