🌷

Rails チュートリアル 9章

に公開

まえがき

Railsチュートリアル9章において押さえておいた方がいいポイントをまとめ、9章の学習内容を俯瞰し整理することを目的とする。


変更を加えたファイル

ファイル名 説明
user.rb 新しくnew_token(クラスメソッド),remember,forget関数を作成した
sessios_controller.rb destroy,createアクションに変更追記した。
sessions_helper.rb remember,current_user,forget,log_outメソッドを変更追記した。
users_login_test.rb 複数のウィンドウを用いた際の挙動についてのテスト、ログインとcookierの挙動についてのテスト
user_test.rb authenticated?メソッドが空である時、エラーにならないようにした変更に対して、テストを追記した。
new.html.erb Remember meのチェックボックスを作成した。
custom.scss チェックボックスに対するスタイルを追加した。
test_helper.rb 2種類のログインのためのメソッドlog_in_asを追加した。

追加したファイル

ファイル名 作成方法 説明
<タイムスタンプ>_add_remember_digest_to_users.rb generate migrationで自動作成 求めがあった時にセッションの情報を覚えておけるように情報を保存するための属性:remember_digestを新たにデータベースに追加する。

トークン使ってしたいこと

セッションの永久保存を目論むわけだが、どうやってこのセッションを取っておくかというと、

  1. ランダムにトークンを発行(remember_token(仮想属性))
  2. トークンをハッシュ化(remember_digest)してデータベース保存
  3. ブラウザのcookiesに保存(有効期限を設定する)するときは、ユーザIDも一緒にしておいて、データベースを検索できるようにする。ただし、ユーザIDも暗号化する。
  1. 暗号化されたIDを複合したIDからデータベースを検索して、そのデータベースのremember_digestとcookiesに保存されたremember_tokenをハッシュ化したものが一致する場合、セッション復元完了。

__

仮想属性ってなんだっけ??

データベースには保存したくないが、データベースの属性のような感覚で扱いたい属性。この属性を作る場合、以下のような方法で作成すれば、読み取り、書き込みが可能で、動作自体はデータベースの属性と同様のものとして扱うことが可能となる。

user.rb
attr_accessor :remember_token

今回の例で言えば、ハッシュかする前のremember_tokenが仮想属性で、ハッシュ化後のremember_digestはデータベースに保存される属性である。


突然出てきたハッシュcookies。君は一体??

どちらかといえば、自動で作られてたハッシュparams寄り。Railsがリクエストごとに作ってくれるオブジェクトであり、ブラウザに保存されているCookieデータが入っている。Cookieに入るのは、次のリクエストにも引き継がれるようなデータである。Cookieに入るデータは基本的に自分で設定することができるという点においてparamsとは異なっている。


ところでテストでよく出てくるassertってなんだっけ?

ということでassertまとめ。

assert

assert
assert <> #値がtrueであればパス

assert_not

assert_not
assert_not <> #値がfalseであればパス

assert_equal

assert_equal
assert_equal <期待する値>,<実際の値> #一致すればパス

assert_not_equal

assert_not_equal
assert_not_equal <期待する値>,<実際の値> #一致しなければパス

assert_difference

assert_difference
# ブロック実行後、メソッドの値が値として設定された値と一致すればパス
assert_difference <メソッド>, <> do
end

assert_no_difference

assert_no_difference
# ブロック実行後、メソッドの値が変化しなければパス
assert_no_difference <メソッド> do
end

assert_template

assert_template
assert_template <パス、URL>  # 指定されたURLのビューが表示されていればパス

assert_select

assert_select
# 指定されたタグがあるか確認し、そのタグが条件を満たしていればパス
# count: <値>、text: <文字列パターン、正規表現OK>などがある
assert_select <タグ、クラス名、id名>, <条件>  

assert_redirected_to

assert_redirected_to
assert_redirected_to <パス、URL> # リダイレクト先が指定されたものと一致していればパス

follow_redirect!

assert_redirected_toで指定されたリダイレクト先に移動する。

assert_response

assert_response
#リクエストに対するレスポンスが指定されたタイプと一致すればパス
assert_response <タイプ>

タイプ一覧

タイプ名 説明 補足
:success ステータスコードが200~299
:see_other ステータスコード303 別の場所を参照せよ
:unprocessable_entity ステータスコード422 処理できないエンティティ
:error ステータスコードが500~599

他にしたこと

  • User.new_tokenを作成。これは、ランダムな文字列で持って新しいトークンを発生させる関数
  • (!!復習)User.digestは、文字列を与えるとハッシュ化してくれる関数
  • User.rememberを作成。これは、remember_tokenを発行し、ハッシュ化、データベースにremember_digestとして保存という一連の作業を行うための関数
  • permanentとは、Railsにある20年を指すcookies設定を行う専用メソッドである。
  • cookiesのメソッドである、encryptedを用いれば渡された値を自動的に暗号化してcookiesに保存してくれる。また、復号にも同様の関数を用いれば良い。
  • cookiesメソッドのdeleteを用いれば指定したシンボルを削除することができる。forgetの際にはこのメソッドを活用する。
  • rememberは、session_shelperに属する関数で、User.rememberとは別物。
  • BCryptはライブラリであり、BCrypt::Password.new("")のようにすることで、ハッシュ化された値を比較可能なオブジェクトにする。(ちなみにこの引数が空だとエラーが発生するので注意)そして、同じくBCryptのis_password?メソッドを繋げることで、is_password("")の文字列をハッシュ化した文字列をと前述のオブジェクトと比較して、ひとしければtrueを返すのである。
  • helperにおいて作成したlog_outはユーザーが明示的にログアウトしたということを示すため、ログアウトされたらrememberの内容も消し去るのが正常な処理である。
  • テストにおいて特定ユーザーとしてログインするための関数はlog_in_asであり、テスト以外の時の用いるlog_inと区別する。
  • assigns(シンボル名)とはRailsで用意されたメソッドであり、シンボル名と同じ名前のインスタンスを呼び出す。:userなら@userを呼び出してくれる。
  • Rubyでは戻り値を書く時わざわざreturnと書かなくても大丈夫。普通に
    remember_digestとかおいておけば戻る。

Discussion