現在,ruby on railsでユーザのログイン状態をブラウザを閉じた後でも有効にする「Remenber me機能」を実装しようとしていて,記憶トークンと記憶ダイジェストの部分でつまづいています.
ちなみに,使用している教材は「Ruby on Railsチュートリアル」というもので,その中でわからない部分があったため質問させていただきました.
前提
まず,記憶ダイジェスト用のマイグレーションを生成しました.
なお,記憶ダイジェストを保存する場所のカラム名は「remember_digest」にしました.
出来上がったUserモデルは以下の通りです.
id | integer |
name | string |
string | |
created_at | datetime |
updated_at | datetime |
password_digest | string |
remember_digest | string |
教材でわからない部分
rememberメソッドの説明
ユーザーを記憶するには、記憶トークンを作成して、そのトークンをダイジェストに変換したものをデータベースに保存します。
さしあたっての実装計画としては、user.rememberメソッドを作成することにします。
user.rememberメソッドは記憶トークンをユーザーと関連付け、トークンに対応する記憶ダイジェストをデータベースに保存します。Userモデルには既にremember_digest属性が追加されていますが、remember_token属性はまだ追加されていません。このためuser.remember_tokenメソッドを使ってトークンにアクセスできるようにし、かつ、トークンをデータベースに保存せずに実装する必要があります。
---------------------- ここからが分からない -------------------------
rememberメソッドの1行目の代入にご注目ください。selfというキーワードを使わないと、Rubyによってremember_tokenという名前のローカル変数が作成されてしまいます。この動作は、Rubyにおけるオブジェクト内部への要素代入の仕様によるものです。今欲しいのはローカル変数ではありません。selfキーワードを与えると、この代入によってユーザーのremember_token属性が期待どおりに設定されます。
なぜローカル変数ではだめなのですか?
コードを見る限りただ値を移行しているだけのように見えるのですが?
でもそうじゃないから,わざわざ仮想の属性を作ってまで,こんなことをしているのだろうと思うのですが,,,
まとめると
- 質問1: わざわざ仮想の属性を作る理由はなんですか?
- 質問2:値をただ移動しているだけではないのなら,何をしている(何が行われている)のかご教授ください.
コード(下から3,4行目が分かりません)
ruby
// ファイルの場所 app/models/user.rb class User < ApplicationRecord attr_accessor :remember_token // ← 新しいトークンを作成するためのnew_tokenメソッドを作成 before_save { self.email = email.downcase } validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } has_secure_password validates :password, presence: true, length: { minimum: 6 } # 渡された文字列のハッシュ値を返す def User.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end # ランダムなトークンを返す def User.new_token SecureRandom.urlsafe_base64 end # 永続セッションのためにユーザーをデータベースに記憶する def remember self.remember_token = User.new_token // ← この部分(なぜローカル変数ではだめなのですか?) update_attribute(:remember_digest, User.digest(remember_token)) // ← この部分 endend
長くなって申し訳ありません.
以上,よろしくお願いいたします.
0 コメント