質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

解決済

Remenber me機能において,わざわざ仮想の属性を作る理由がわからない

OHASI
OHASI

総合スコア88

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

1回答

0グッド

0クリップ

186閲覧

投稿2022/11/17 09:39

 現在,ruby on railsでユーザのログイン状態をブラウザを閉じた後でも有効にする「Remenber me機能」を実装しようとしていて,記憶トークンと記憶ダイジェストの部分でつまづいています.

ちなみに,使用している教材は「Ruby on Railsチュートリアル」というもので,その中でわからない部分があったため質問させていただきました.

前提

まず,記憶ダイジェスト用のマイグレーションを生成しました.
なお,記憶ダイジェストを保存する場所のカラム名は「remember_digest」にしました.
出来上がったUserモデルは以下の通りです.

idinteger
namestring
emailstring
created_atdatetime
updated_atdatetime
password_digeststring
remember_digeststring

教材でわからない部分

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

長くなって申し訳ありません.
以上,よろしくお願いいたします.

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

1

ベストアンサー

質問1: わざわざ仮想の属性を作る理由はなんですか?

あとでremember_tokenを使う必要があるためです。ダイジェスト化した後のremember_digestからremember_tokenを復元することはできません。

投稿2022/11/17 09:48

maisumakun

総合スコア141365

OHASI👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

OHASI

2022/11/17 12:03

なるほど! 分かりやすい解説ありがとうございました.

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。