0
0

More than 3 years have passed since last update.

Ruby on Rails チュートリアル(第4版) 第12章

Posted at

12.1.1 演習

1.この時点で、テストスイートが greenになっていることを確認してみましょう。
 省略

2.表 12.1の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: アカウント有効化で行った演習 (11.1.1.1) と同じ理由です。
 メールでURLを送付するから。

12.1.2 演習

1.リスト 12.4のform_forメソッドでは、なぜ@password_resetではなく:password_resetを使っているのでしょうか? 考えてみてください。
 よく分からなかったので、Railsのform_forにシンボルを与えるときはどのようなときか?こちらを参考に。
 複数のビューでform_forメゾット使う時に使い分けてくれるって感じなのかな?

12.1.3 演習

1.試しに有効なメールアドレスをフォームから送信してみましょう (図 12.6)。どんなエラーメッセージが表示されたでしょうか?
 wrong number of arguments (given 1, expected 0)

2.コンソールに移り、先ほどの演習課題で送信した結果、(エラーと表示されてはいるものの) 該当するuserオブジェクトにはreset_digestとreset_sent_atがあることを確認してみましょう。また、それぞれの値はどのようになっていますか?


 SQL (2.5ms)  UPDATE "users" SET "reset_digest" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["reset_digest", "$2a$10$HBKO270gNm.cJbXLUiK42.kbtr6rHK54A5shhjJ3AuyxdZ8CwKR2G"], ["updated_at", "2020-07-23 14:35:37.103987"], ["id", 1]]
   (7.2ms)  commit transaction
   (0.0ms)  begin transaction
  SQL (1.5ms)  UPDATE "users" SET "updated_at" = ?, "reset_sent_at" = ? WHERE "users"."id" = ?  [["updated_at", "2020-07-23 14:35:37.129134"], ["reset_sent_at", "2020-07-23 14:35:37.128433"], ["id", 1]]

12.2.1 演習

1.ブラウザから、送信メールのプレビューをしてみましょう。「Date」の欄にはどんな情報が表示されているでしょうか?
 Date:Thu, 23 Jul 2020 14:43:18 +0000

2.パスワード再設定フォームから有効なメールアドレスを送信してみましょう。また、Railsサーバーのログを見て、生成された送信メールの内容を確認してみてください。

    <h1>Password reset</h1>

<p>To reset your password click the link below:</p>

<a href="https://f85f995d89d545089c7ba0ef0e279d4c.vfs.cloud9.ap-northeast-1.amazonaws.com/password_resets/IcIj_J0Zlrd0_hygj_87Nw/edit?email=example%40railstutorial.org">Reset password</a>

<p>This link will expire in two hours.</p>

<p>
If you did not request your password to be reset, please ignore this email and
your password will stay as it is.
</p>
  </body>

3.コンソールに移り、先ほどの演習課題でパスワード再設定をしたUserオブジェクトを探してください。オブジェクトを見つけたら、そのオブジェクトが持つreset_digestとreset_sent_atの値を確認してみましょう。

>> user = User.find_by(id:1)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2020-07-18 13:20:13", updated_at: "2020-07-23 14:41:35", password_digest: "$2a$10$9v5S4oJk16x9pfbMXkf/ievaQhPA50XBMqFztNrZnqj...", remember_digest: nil, admin: true, activation_digest: "$2a$10$OBqUPKe0HwaDUBtqARDRzO9NSFaoKAPHmjNzuTvoqz1...", activated: true, activated_at: "2020-07-18 13:20:13", reset_digest: "$2a$10$fAY5aKaX/6mcO7tbFS/AZOWhoYOcj3CgMvjiRgx/AEd...", reset_sent_at: "2020-07-23 14:41:35">

1.メイラーのテストだけを実行してみてください。このテストは greenになっているでしょうか?
 GREEN。

2.リスト 12.12にある2つ目のCGI.escapeを削除すると、テストが redになることを確認してみましょう。
 REDになった。

12.3.1 演習

1.12.2.1.1で示した手順に従って、Railsサーバーのログから送信メールを探し出し、そこに記されているリンクを見つけてください。そのリンクをブラウザから表示してみて、図 12.11のように表示されるか確かめてみましょう
 省略

2.先ほど表示したページから、実際に新しいパスワードを送信してみましょう。どのような結果になるでしょうか?

 Unknown action
 The action 'update' could not be found for PasswordResetsController
 エラーでドキッ!updateアクションまだ書いてないもんね。

12.3.2 演習

1.12.2.1.1で得られたリンク (Railsサーバーのログから取得) をブラウザで表示し、passwordとconfirmationの文字列をわざと間違えて送信してみましょう。どんなエラーメッセージが表示されるでしょうか?
 Password confirmation doesn't match Password

2.コンソールに移り、パスワード再設定を送信したユーザーオブジェクトを見つけてください。見つかったら、そのオブジェクトのpassword_digestの値を取得してみましょう。次に、パスワード再設定フォームから有効なパスワードを入力し、送信してみましょう (図 12.13)。パスワードの再設定は成功したら、再度password_digestの値を取得し、先ほど取得した値と異なっていることを確認してみましょう。ヒント: 新しい値はuser.reloadを通して取得する必要があります。

 password_digest: "$2a$10$B6393nyZgIhwI4l1sFvZqe7ut877uijFjhDoVSizLdy..."
 password_digest: "$2a$10$qFFzrhOelczLx3DO.2p6quDaFlV5T1ciSrCbDXTe44d..."

12.3.3 演習

1.リスト 12.6にあるcreate_reset_digestメソッドはupdate_attributeを2回呼び出していますが、これは各行で1回ずつデータベースへ問い合わせしていることになります。リスト 12.20に記したテンプレートを使って、update_attributeの呼び出しを1回のupdate_columns呼び出しにまとめてみましょう (これでデータベースへの問い合わせが1回で済むようになります)。また、変更後にテストを実行し、 greenになることも確認してください。ちなみにリスト 12.20にあるコードには、前章の演習 (リスト 11.39) の解答も含まれています。
 update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)

2.リスト 12.21のテンプレートを埋めて、期限切れのパスワード再設定で発生する分岐 (リスト 12.16) を統合テストで網羅してみましょう (12.21 のコードにあるresponse.bodyは、そのページのHTML本文をすべて返すメソッドです)。期限切れをテストする方法はいくつかありますが、リスト 12.21でオススメした手法を使えば、レスポンスの本文に「expired」という語があるかどうかでチェックできます (なお、大文字と小文字は区別されません)。
 assert_match /expired/i, response.body

3.2時間経ったらパスワードを再設定できなくする方針は、セキュリティ的に好ましいやり方でしょう。しかし、もっと良くする方法はまだあります。例えば、公共の (または共有された) コンピューターでパスワード再設定が行われた場合を考えてみてください。仮にログアウトして離席したとしても、2時間以内であれば、そのコンピューターの履歴からパスワード再設定フォームを表示させ、パスワードを更新してしまうことができてしまいます (しかもそのままログイン機構まで突破されてしまいます!)。この問題を解決するために、リスト 12.22のコードを追加し、パスワードの再設定に成功したらダイジェストをnilになるように変更してみましょう5 。
 省略

4.リスト 12.18に1行追加し、1つ前の演習課題に対するテストを書いてみましょう。ヒント: リスト 9.25のassert_nilメソッドとリスト 11.33のuser.reloadメソッドを組み合わせて、reset_digest属性を直接テストしてみましょう。
  assert_nil user.reload.reset_digest

12.4 演習

1.production環境でユーザー登録を試してみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?
 省略
2.メールを受信できたら、実際にメールをクリックしてアカウントを有効化してみましょう。また、Heroku上のログを調べてみて、有効化に関するログがどうなっているのか調べてみてください。ヒント: ターミナルからheroku logsコマンドを実行してみましょう。
 省略
3.アカウントを有効化できたら、今度はパスワードの再設定を試してみましょう。正しくパスワードの再設定ができたでしょうか?
 We're sorry, but something went wrong.
 If you are the application owner check the logs for more information.
 エラーが出てしまった。heroku logsで確認してもエラー確認出来ず。メール送ったことになってる。
 
 $ heroku run rails db:migrateをもう一度やってみる。ダメ。
 $ heroku run rake db:seedもやってみる。ダメ。
 DBをリセットしてみた。
 やっぱり駄目だった・・・どうして。

 ローカル環境では問題ない、エラーが出るのはメールが送信される時だけなのでSendGrid凍結の疑い。
 Railsチュートリアル11章 SendGrid 凍結問題を解決する
 こちらを参考に新しくデプロイし直ししたら無事解決!また凍結されるかもしれないけれども。
 なんとか無事に12章終わり!

メモ

- user.reloadで新しい値を取得できる(Rails console)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0