##11.1.1 演習
1.現時点でテストスイートを実行すると greenになることを確認してみましょう。
GREEN。
2.表 11.2の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: 私達はこれからメールで名前付きルートを使います。
メールで認証用のURLを送るから。
##11.1.2 演習
1.本項での変更を加えた後、テストスイートが green のままになっていることを確認してみましょう。
GREEN。
2.コンソールからUserクラスのインスタンスを生成し、そのオブジェクトからcreate_activation_digestメソッドを呼び出そうとすると (Privateメソッドなので) NoMethodErrorが発生することを確認してみましょう。また、そのUserオブジェクトからダイジェストの値も確認してみましょう。
>> user = User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2020-07-18 13:20:13", updated_at: "2020-07-18 13:20:13", 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">
>> user.create_activation_digest
Traceback (most recent call last):
1: from (irb):2
NoMethodError (private method `create_activation_digest' called for #<User:0x00000000038fe550>)
Did you mean? restore_activation_digest!
>> user.activation_digest
=> "$2a$10$OBqUPKe0HwaDUBtqARDRzO9NSFaoKAPHmjNzuTvoqz1S/M4U87mLG"
3.リスト 6.34で、メールアドレスの小文字化にはemail.downcase!という (代入せずに済む) メソッドがあることを知りました。このメソッドを使って、リスト 11.3のdowncase_emailメソッドを改良してみてください。また、うまく変更できれば、テストスイートは成功したままになっていることも確認してみてください。
def downcase_email
email.downcase!
end
##11.2.1 演習
1.コンソールを開き、CGIモジュールのescapeメソッド (リスト 11.15) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで"Don't panic!"をエスケープすると、どんな結果になりますか?
>> CGI.escape("Don't panic!")
=> "Don%27t+panic%21"
##11.2.2 演習
1.Railsのプレビュー機能を使って、ブラウザから先ほどのメールを表示してみてください。「Date」の欄にはどんな内容が表示されているでしょうか?
Sample App
Hi Example User,
Welcome to the Sample App! Click on the link below to activate your account:
Activate
##11.2.3 演習
1.この時点で、テストスイートが greenになっていることを確認してみましょう。
GREEN。
2.リスト 11.20で使ったCGI.escapeの部分を削除すると、テストが redに変わることを確認してみましょう。
RED。
##11.2.4 演習
1.新しいユーザーを登録したとき、リダイレクト先が適切なURLに変わったことを確認してみましょう。その後、Railsサーバーのログから送信メールの内容を確認してみてください。有効化トークンの値はどうなっていますか?
<a href="https://f85f995d89d545089c7ba0ef0e279d4c.vfs.cloud9.ap-northeast-1.amazonaws.com/account_activations/gQLsi3XDKQNoPHjOqKimrQ/edit?email=muramako%40muramako.jp">Activate</a>
2.コンソールを開き、データベース上にユーザーが作成されたことを確認してみましょう。また、このユーザーはデータベース上にはいますが、有効化のステータスがfalseのままになっていることを確認してください。
>> user = User.find_by(name:"muramako")
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."name" = ? LIMIT ? [["name", "muramako"], ["LIMIT", 1]]
=> #<User id: 101, name: "muramako", email: "muramako@muramako.jp", created_at: "2020-07-18 14:07:24", updated_at: "2020-07-18 14:07:24", password_digest: "$2a$10$3olDXZZfbo.4YR93dFDh0ezYB5qJ8ghZ8k99kw.g08....", remember_digest: nil, admin: false, activation_digest: "$2a$10$7e8MyPJR0Ow.5/S0RjAsSuBFTH4bMhtg4Eo3GzQ5uwY...", activated: false, activated_at: nil>
##11.3.1 演習
1.コンソール内で新しいユーザーを作成してみてください。新しいユーザーの記憶トークンと有効化トークンはどのような値になっているでしょうか? また、各トークンに対応するダイジェストの値はどうなっているでしょうか?
>> user.remember_token
=> nil
>> user.remember_digest
=> nil
>> user.activation_token
=> "H2toQkBzYcrxqv9bNRdNfQ"
>> user.activation_digest
=> "$2a$10$awE0Y8KiWao4cKIVy51h9uyHcDxohzPKuZ1lMSudqpaZI/cJNNU/K"
2.リスト 11.26で抽象化したauthenticated?メソッドを使って、先ほどの各トークン/ダイジェストの組み合わせで認証が成功することを確認してみましょう。
activationのほうは自力でいけたのですがrememberがnilでカンニングしてしまった。
user.rememberを実行してremember_tokenを作らないとダメだった。
>> user.remember
(0.1ms) begin transaction
SQL (6.0ms) UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ? [["updated_at", "2020-07-18 14:39:36.633647"], ["remember_digest", "$2a$10$SNB1le.uJ1PxHmmlrIAEe.RpGrBglEKf.knOjzumx1vzqdR0HD3ZC"], ["id", 104]]
(4.2ms) commit transaction
=> true
>> user.authenticated?(:remember, user.remember_token)
=> true
>> user.authenticated?(:activation, user.activation_token)
=> true
##11.3.2 演習
1.コンソールから、11.2.4で生成したメールに含まれているURLを調べてみてください。URL内のどこに有効化トークンが含まれているでしょうか?
f85f995d89d545089c7ba0ef0e279d4c.vfs.cloud9.ap-northeast-1.amazonaws.com/account_activations/gQLsi3XDKQNoPHjOqKimrQ/
edit?email=muramako%40muramako.jp"
2.先ほど見つけたURLをブラウザに貼り付けて、そのユーザーの認証に成功し、有効化できることを確認してみましょう。また、有効化ステータスがtrueになっていることをコンソールから確認してみてください。
>> user.activated
=> true
##11.33テストでエラー。
GREENのはずのテストがエラーに。
11.32のcreateアクション、演習をやってる場合user
→@user
にしないとダメなんだった。
##11.3.3 演習
1.リスト 11.35にあるactivateメソッドはupdate_attributeを2回呼び出していますが、これは各行で1回ずつデータベースへ問い合わせしていることになります。リスト 11.39に記したテンプレートを使って、update_attributeの呼び出しを1回のupdate_columns呼び出しにまとめてみましょう (これでデータベースへの問い合わせが1回で済むようになります)。また、変更後にテストを実行し、 greenになることも確認してください。
def activate
update_columns(activated: true, activated_at: Time.zone.now)
end
2.現在は、/usersのユーザーindexページを開くとすべてのユーザーが表示され、/users/:idのようにIDを指定すると個別のユーザーを表示できます。しかし考えてみれば、有効でないユーザーは表示する意味がありません。そこで、リスト 11.40のテンプレートを使って、この動作を変更してみましょう9 。なお、ここで使っているActive Recordのwhereメソッドについては、13.3.3でもう少し詳しく説明します。
def index
@users = User.where(activated: true).paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
redirect_to root_url and return unless @user.activated?
end
##11.4 演習
1.実際に本番環境でユーザー登録をしてみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?
届いた。
2.メールを受信できたら、実際にメールをクリックしてアカウントを有効化してみましょう。また、Heroku上のログを調べてみて、有効化に関するログがどうなっているのか調べてみてください。ヒント: ターミナルからheroku logsコマンドを実行してみましょう。
SQL (1.9ms) UPDATE "users" SET "activated" = 't', "activated_at" = '2020-07-18 15:12:42.493073' WHERE "users"."id" = $1 [["id", 101]]