Rails Diary

プログラミングの学習記録です。

パスワード再設定課題メモ

★ 完成イメージに対し、どういった実装をするのか必要なのかを洗い出しておくと。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.erbreset_password_email.text.erbと二つ存在する理由について

まず、html形式の方が色をつけられたり、画像を挿入できたりバリエーションに富んだメールを送ることができる。けれどもブラウザによってはhtml形式のメールを表示することができないものもあるらしいので、そういったクライアントに対してメール本文が確認できるように、テキスト形式のものも用意しておく。