【137日目】【1日20分のRailsチュートリアル】【第10章】パスワードリセットのupdateアクションを実装する
今日は「10.2.4 パスワードを再設定する」のupdateアクションを定義するところから。
10.2.4 パスワードを再設定する
リスト10.51のeditアクションに対応するupdateアクションを定義するには、4通りの場合分けに対応する必要があります:
パスワード再設定の期限が切れている場合、更新に成功した場合、更新が失敗した場合 (パスワードが正しくないなど)、更新が失敗した場合 (一見更新が成功したように見えるがパスワードが2つとも空欄) です。
いっぱい確認しなきゃいけないことあるんだな…。
app/controllers/password_resets_controller.rb
: before_action :check_expiration, only: [:edit, :update] : def update if params[:user][:password].empty? @user.errors.add(:password, "can't be empty") render 'edit' elsif @user.update_attributes(user_params) log_in @user flash[:success] = "Password has been reset." redirect_to @user else render 'edit' end end private def user_params params.require(:user).permit(:password, :password_confirmation) end : # 再設定用トークンが期限切れかどうかを確認する def check_expiration if @user.password_reset_expired? flash[:danger] = "Password reset has expired." redirect_to new_password_reset_url end end end
上のコードが動作するには、このpassword_reset_expired?メソッドを定義する必要があります。
(中略)
reset_sent_at < 2.hours.ago
この「<」記号を「〜より少ない」と読んでしまうと、「パスワード再設定メール送信時から経過した時間が、2時間より少ない場合」となってしまい、ここで行おうとしていることと反対の意味になってしまいます。
えー!難しいな…。
2.hours.ago
は「現在時刻より2時間前の時間」を取得できるので、2時間前の時間がreset_sent_at
(パスワード再設定メールを送信した時間)より大きい場合は2時間経過していることになり、trueを返す、ってことか。
こう考えると別におかしくないな。
app/models/user.rb
# パスワード再設定の期限が切れている場合はtrueを返す def password_reset_expired? reset_sent_at < 2.hours.ago end
リスト10.53のコードを使用すると、リスト10.52のupdateアクションが動作するようになります。
動作見てみよう。
前回起動できなかったサーバーは何もしてないのに起動できるようになってた。
何事もなかったかのようにサーバーを起動して、
$ rails server -b $IP -p $PORT
試しに以前パスワードリセットしてみたときのURLにアクセスしてみる。
当然パスワード再設定の期限は切れているのでエラーメッセージが表示されました。
パスワード再設定メールを再度送信して、今度は空のパスワードを再設定しようとしてみる。
エラーメッセージが表示されました。
エラーにならないパスワードを再設定するとパスワード再設定に成功した旨のメッセージが表示され、プロフィール画面が表示されました。
問題なさそう。
今日の学習時間は【25分】。
次は「10.2.5 パスワードの再設定をテストする」から。