Rails Tutorialやってみた!37(12章-3)

公開日:2019-05-06
最終更新:2019-05-06

100DaysOfCode 61/100

今日やること

  • PasswordReset機能の実装とテスト(12章終了)

PasswordReset機能の実装

メイラーのリンクを動かすための記述をしていきます。

editアクションとupdateアクションの双方で正しいユーザーが存在していることを確認するため、before_actionを設定します。

before_action :get_user,   only: [:edit, :update] before_action :valid_user, only: [:edit, :update]  
  • get_userはメールアドレスからユーザーを取得するメソッド
  • valid_userは取得したユーザーのactivated?authenticated?を確認し、無効なユーザーの場合は強制リダイレクトするメソッド

パスワードを更新する

今回はeditupdate2つのアクションを用意しています。

AccountActivationsコントローラのeditアクションでは、ユーザーの有効化ステータスをfalseからtrueに変更しましたが、今回の場合はフォームから新しいパスワードを送信するようになっています。したがって、フォームからの送信に対応するupdateアクションが必要になります。

11章と異なり、「フォームから受け取ったデータを使って更新する」という手順が一つ増えているということですね。

パスワードが空文字だった場合の処理

今回の小難しい問題点は、パスワードが空文字だった場合の処理です。というのも、以前Userモデルを作っていたときに、パスワードが空でも良い (リスト 10.13のallow_nil) という実装をしたからです。したがって、このケースについては明示的にキャッチするコードを追加する必要があります。

updateメソッドには、

if params[:user][:password].empty?  
  @user.errors.add(:password, :blank)  
  render 'edit'  

このようにパスワードが空だったときにエラーを返す処理を追加します。

トークンの有効期限チェック

def check_expiration  
  if @user.password_reset_expired?  
.  
.  

beforeアクションで有効期限をチェックするには、このpassword_reset_expired?というメソッドをUserモデルに持たせる必要があります。

今回は2時間を有効期限とします。

reset_sent_at < 2.hours.ago  

Rubyではこのように記述することで現在時刻からの経過時間を判定することができますが、<記号が少しわかりにくいです。

ここでは<○○よりも前と読み替えましょう。

つまり、このコードはトークンの作成時間が2時間よりも前(古い)であればtrue(=トークンを無効にする)となります。

テスト

これまで通り、パスワード再設定の成功失敗を想定してテストを書いていきます。

新しい要素はほぼないのですが、コードの量がこれまでと比較してもなかなか多いです。
これをじっくり読んで理解することはよい訓練になりそうですね。

assert_select "input[name=email][type=hidden][value=?]", user.email  

assert_selectでhiddenフォームに入力されたパラメータが正しいことを確認できるのはちょっとした応用ポイントです。

演習

1

これは11章と同じくupdate_columnsの使い方の確認ですね。

update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)  

複数の属性を更新する際はupdate_attributeよりもスマートです。

2

3時間前に作成されたトークンを使った場合、パスワード更新が弾かれることを確認するテストを書いてみます。

check_expirationメソッドによって、パスワード更新が弾かれた場合はリダイレクト後に「Password reset has expired.」というflashメッセージが表示されます。

これをチェックする手法を取りましょう。

assert_match "expired", response.body  

response.bodyを参照することで、文字通りHTTPレスポンスボディの全体を確認してくれるので確実です。

3

パスワードの更新が成功した場合、トークンダイジェストは不要となります。

むしろダイジェストが残っていることで、共用PCなどの環境下では第三者に再びパスワードを変更されてしまうリスクを孕んでいるともいえます。

パスワード更新成功時に:reset_digestnilに上書きし、削除してしまいましょう。update_attributeを使うだけなので実装も簡単です。

終わりに

12章はこれまでの内容の理解度が試される内容でした。
個人的にトークン関連の内容は難しいと感じている部分なので、Tutorial完走後にしっかり復習していきたいと思います。

13章はオリジナルアプリの制作時にある程度予習しているので、比較的スムーズに進められるのではないかと思います。頑張ります!

次回以降やること

  • 13章
記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@tammcの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする