現在,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
1// ファイルの場所 2app/models/user.rb 3 4class User < ApplicationRecord 5 attr_accessor :remember_token // ← 新しいトークンを作成するためのnew_tokenメソッドを作成 6 before_save { self.email = email.downcase } 7 validates :name, presence: true, length: { maximum: 50 } 8 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i 9 validates :email, presence: true, length: { maximum: 255 }, 10 format: { with: VALID_EMAIL_REGEX }, 11 uniqueness: { case_sensitive: false } 12 has_secure_password 13 validates :password, presence: true, length: { minimum: 6 } 14 15 # 渡された文字列のハッシュ値を返す 16 def User.digest(string) 17 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 18 BCrypt::Engine.cost 19 BCrypt::Password.create(string, cost: cost) 20 end 21 22 # ランダムなトークンを返す 23 def User.new_token 24 SecureRandom.urlsafe_base64 25 end 26 27 # 永続セッションのためにユーザーをデータベースに記憶する 28 def remember 29 self.remember_token = User.new_token // ← この部分(なぜローカル変数ではだめなのですか?) 30 update_attribute(:remember_digest, User.digest(remember_token)) // ← この部分 31 end 32end
長くなって申し訳ありません.
以上,よろしくお願いいたします.
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/11/17 12:03