らくだ🐫にもできるRailsチュートリアル|11.1

11章でやること
アカウントを有効化するためのメール認証システムを作る!

  1. ユーザーの初期状態は「有効化されていない」(unactivated) にしておく。
  2. ユーザー登録が行われたときに、有効化トークンと、それに対応する有効化ダイジェストを生成する。
  3. 有効化ダイジェストはデータベースに保存しておき、有効化トークンはメールアドレスと一緒に、ユーザーに送信する有効化用メールのリンクに仕込んでおく
  4. ユーザーがメールのリンクをクリックしたら、アプリケーションはメールアドレスをキーにしてユーザーを探し、データベース内に保存しておいた有効化ダイジェストと比較することでトークンを認証する。
  5. ユーザーを認証できたら、ユーザーのステータスを「有効化されていない」から「有効化済み」(activated) に変更する。

うむわからん!

こうやって書くとよくわからないけど、
パスワードや記憶トークンの仕組みと似た点が多いとの事なので、記事を見直しつつゆっくり理解しながら進めていきましょうそうしましょう。

11.1 AccountActivationsリソース

セッション機能 (8.1) を使って、アカウントの有効化という作業を「リソース」としてモデル化することにします。アカウントの有効化リソースはActive Recordのモデルとはこの際関係ないので、両者を関連付けることはしません。その代わりに、この作業に必要なデータ (有効化トークンや有効化ステータスなど) をUserモデルに追加することにします。

また、アカウント有効化もリソースの使い方に今までとは異なる点があるので注意!

有効化用のリンクにアクセスして有効化のステータスを変更する部分では、RESTのルールに従うとPATCHリクエストとupdateアクションになるべきです (表 7.1)。しかし、有効化リンクはメールでユーザーに送られることを思い出してください。ユーザーがこのリンクをクリックすれば、それはブラウザで普通にクリックしたときと同じであり、その場合ブラウザから発行されるのは (updateアクションで使うPATCHリクエストではなく) GETリクエストになってしまいます。このため、ユーザーからのGETリクエストを受けるために、(本来であればupdateのところを) editアクションに変更して使っていきます。

やっぱり文章で説明されてもよくわからないので進めながら理解できるように頑張りたい(希望)

11.1.1 AccountActivationsコントローラ

有効化のメールに必要な名前付きルート

詳しくは11.2.1との事だけど
有効化のメールに含まれるURLにeditアクションへの名前付きルートが必要になる

なので名前付きルートを使えるように設定する

これにより
/account_activation/<token>/editにgetのリクエストが送られるとaccount_activationsコントローラーのeditアクションが実行されるようになる
名前付きルートのedit_account_activation_url(token)も使えるようになる

演習

  1. 現時点でテストスイートを実行すると greenになることを確認してみましょう。
  2. 表 11.2の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: 私達はこれからメールで名前付きルートを使います。
  1. green
  2. メール本文のURLからアクセスするから
    (因みに_pathは相対パスを返し_urlは絶対パスを返すヤツ)

11.1.2 AccountActivationのデータモデル

アカウント有効化メールには一意の有効化トークンが必要

パスワードの実装 (第6章) や記憶トークンの実装 (第9章) と同じように仮想的な属性を使ってハッシュ化した文字列をデータベースに保存するようにします。

具体的にはこんな感じになる

あと、本文では使わないけどユーザーを有効にしたときの日時も念のために記録できるようにしておく

  • activation_digest:string
  • activated:boolean
  • activated_at:datetime

この3つの属性をUserモデルに追加する

Activationトークンのコールバック

ユーザーが新しい登録を完了するためには必ずアカウントの有効化が必要になるのですから、有効化トークンや有効化ダイジェストはユーザーオブジェクトが作成される前に作成しておく必要があります。

メースアドレスを保存する前に全て小文字に変換するように指定した際は
before_saveコールバックにdowncaseメソッドを関連付けてオブジェクトの保存の直前に実行されるようにしたけど
今回は保存直前ではなくオブジェクトが作成された時にのみコールバックを呼び出したい!
よってこう↓

createの直前にcreate_activation_digestメソッドを呼び出している
→create_activation_digestメソッドは外部から見えないようにprivateキーワードを指定して隠ぺい!

rememberメソッドとの違い

コールバックに関連付けるメソッドは記憶トークンや記憶ダイジェストのために作ったメソッドを使いまわしてるけどもちろん違いもある!

記憶トークンやダイジェストは既にデータベースにいるユーザーのために作成されるのでupdate_attributeを使って情報を更新・保存しているが
before_createコールバックの方はユーザーが作成される前に呼び出されることなので更新される属性がない→新しく取得
以上をもとにUserモデルにアカウント有効化のコードを追加
また以下も併せて

  • せっかくなので(?)メールアドレスを小文字にするメソッドもメソッド参照に切り替える
  • 有効化トークンは本質的に仮のものでなければならないのでactivation_token属性をattr_accessorに追加

サンプルユーザーの生成とテスト

先に進む前に、サンプルデータとfixtureも更新してスムーズにテストできるように準備をしておく!

なお、Time.zone.nowはRailsの組み込みヘルパーであり、サーバーのタイムゾーンに応じたタイムスタンプを返します。

データベースのリセットとサンプルデータを再度生成

演習

  1. 本項での変更を加えた後、テストスイートが green のままになっていることを確認してみましょう。
  2. コンソールからUserクラスのインスタンスを生成し、そのオブジェクトからcreate_activation_digestメソッドを呼び出そうとすると (Privateメソッドなので) NoMethodErrorが発生することを確認してみましょう。また、そのUserオブジェクトからダイジェストの値も確認してみましょう。
  3. リスト 6.34で、メールアドレスの小文字化にはemail.downcase!という (代入せずに済む) メソッドがあることを知りました。このメソッドを使って、リスト 11.3のdowncase_emailメソッドを改良してみてください。また、うまく変更できれば、テストスイートは成功したままになっていることも確認してみてください。

1.
green

2.

3.

テストはgreen

まとめとか感想

アカウント有効化メール実装の準備
次からが本番ですね!

らくだ🐫にもできるRailsチュートリアルとは

「ド」が付く素人のらくだ🐫が勉強するRailsチュートリアルの学習記録です。
自分用に記録していますが、お役に立つことがあれば幸いです。

調べたとはいえらくだ🐫なりの解釈や説明が含まれます。間違っている部分もあるかと思います。そんな所は教えて頂けますと幸いなのですが、このブログにはコメント機能がありません💧お手数おかけしますがTwitterなどでご連絡いただければ幸いです