###パスワードを更新する
今回の場合はフォームから新しいパスワードを送信するようになっています。
フォームからの送信に対応するupdateアクションが必要になります。
updateアクションでは、次の4つのケースを考慮する必要があります。
1.パスワード再設定の有効期限が切れていないか
2.無効なパスワードであれば失敗させる(失敗した理由も表示する)
3.新しいパスワードが空文字列になっていないか(ユーザー情報の編集ではOKだった)
4.新しいパスワードが正しければ、更新する
####パスワード再設定のupdateアクション
app/controllers/password_resets_controller.rb
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update] # (1)への対応
# その前に行う
.
.
.
def update
if params[:user][:password].empty? # (3)への対応
# パスワードが空文字列かどうか?
@user.errors.add(:password, :blank)
# errors.add(:base, '名前の文字数オーバー')
# なのでメッセージを表示する
render 'edit'
# 編集画面に行く。
elsif @user.update(user_params) # (4)への対応
# 新しいパスワードが正しければ、更新する
log_in @user
flash[:success] = "Password has been reset."
redirect_to @user
else
render 'edit' # (2)への対応
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
# requireメソッドで受け取るパラメータ群を、permitメソッドで利用可能なパラメータ名を指定
end
.
.
.
# トークンが期限切れかどうか確認する
def check_expiration
if @user.password_reset_expired?
# 期限が切れているか?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
####Userモデルにパスワード再設定用メソッドを追加する
app/models/user.rb
class User < ApplicationRecord
.
.
.
# パスワード再設定の期限が切れている場合はtrueを返す
def password_reset_expired?
reset_sent_at < 2.hours.ago
# 2時間前より前の時間
end
.
.
.
end
###演習
1.
12.2.1.1で得られたリンク(Railsサーバーのログから取得)をブラウザで表示し、passwordとconfirmationの文字列をわざと間違えて送信してみましょう。どんなエラーメッセージが表示されるでしょうか?
Password confirmation doesn't match Password
コンソールに移り、パスワード再設定を送信したユーザーオブジェクトを見つけてください。見つかったら、そのオブジェクトのpassword_digestの値を取得してみましょう。次に、パスワード再設定フォームから有効なパスワードを入力し、送信してみましょう(図 12.13)。パスワードの再設定は成功したら、再度password_digestの値を取得し、先ほど取得した値と異なっていることを確認してみましょう。ヒント: 新しい値はuser.reloadを通して取得する必要があります。
>> user = User.find_by(email: "example@railstutorial.org")
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "example@railstutorial.org"], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2021-10-17 05:28:48", updated_at: "2021-10-20 14:25:39", password_digest: [FILTERED], remember_digest: nil, admin: true, activation_digest: "$2a$12$x4xVHmtrDFjVPFFWav31UebLY8r9sdT8ImzSXGSrnqt...", activated: true, activated_at: "2021-10-17 05:28:48", reset_digest: "$2a$12$FhfOA3Y7VPJ3TJJ5nNUEkuSH0hkGrrW15uyYE9EwbrC...", reset_sent_at: "2021-10-20 14:25:39">
>> user.password_digest
=> "$2a$12$GusJ71vphWBKR7LjQGrkfeHiAWFbIoCWQfodotlR**************"
パスワードを変化させるのはちょっと抵抗があるのでやめておく。