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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

2回答

1013閲覧

rails tutorial 第9章 remember_token アトリビュートアクセッサーが上手くいかない

tatuski_arakaki

総合スコア11

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2019/07/19 09:40

前提・実現したいこと

rails tutorial第9章でremember me機能をつける為に
アトリビュートアクセッサーを使ってremember_tokenという
アクセッサーを定義したのですがエラーが出てしまいます。

発生している問題・エラーメッセージ

ERROR["test_current_user_returns_right_user_when_session_is_nil", SessionsHelperTest, 1.2696126079999885] test_current_user_returns_right_user_when_session_is_nil#SessionsHelperTest (1.27s) NoMethodError: NoMethodError: undefined method `remember_token=' for #<User:0x00000000076326d8> Did you mean? remember_token       = app/models/user.rb:27:in `remember' app/helpers/sessions_helper.rb:9:in `remember' test/helpers/sessions_helper_test.rb:7:in `setup' ちなみにテストを走らせるとこのようなエラーになります。

該当のソースコード

ruby

1class User < ApplicationRecord 2 attr_accessor :remember_token       # アトリビュートアクセッサー を使ってセッターメソッドとゲッターメソッドを実装することができる (データベースには反映されないけどメソッドとして使えるデータを保持する場所) 3 has_many :microposts, dependent: :destroy 4 before_save {email.downcase!} 5 validates :name, presence: true, length: { maximum: 50 } 6 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i 7 validates :email, presence: true, length: { maximum: 255 }, 8 format: { with: VALID_EMAIL_REGEX }, 9 uniqueness: {case_sensitive: false} 10 has_secure_password 11 validates :password, presence: true, length: { minimum: 6 }, allow_nil: true 12 13 # 渡された文字列のハッシュ値を返す 14 def self.digest(string) 15 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 16 BCrypt::Engine.cost 17 BCrypt::Password.create(string, cost: cost) 18 end 19 20 # ランダムなトークンを返す 21 def User.new_token 22 SecureRandom.urlsafe_base64 23 end 24 25 # 永続セッションのためにユーザーをデータベースに記憶する 26 def remember 27 self.remember_token = User.new_token 28 update_attribute(:remember_digest, User.digest(remember_token)) 29 end 30 31 # 渡されたトークンがダイジェストと一致したらtrueを返す 32 def authenticated?(remember_token) 33 return false if remember_digest.nil? 34 BCrypt::Password.new(remember_digest).is_password?(remember_token) 35 end 36 37 # ユーザーのログイン情報を破棄する 38 def forget 39 update_attribute(:remember_digest, nil) 40 end 41 42end

試したこと

rails consoleを使って rememberを実行すると

2.6.3 :017 > user = User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2019-07-17 09:41:35", updated_at: "2019-07-17 09:41:35", password_digest: "$2a$10$JDI8PEk25zNy8PIuJLqLVevU9jblPNaZ/sZN8AMjwNT...", remember_digest: nil, admin: true>
2.6.3 :018 > user.remember
Traceback (most recent call last):
2: from (irb):18
1: from app/models/user.rb:27:in remember' NoMethodError (undefined method remember_token=' for #User:0x0000000002e40910)
Did you mean? remember_token       =
2.6.3 :019 >

と、remember_tokenでnomethoderrorが出てしまいます。

補足情報(FW/ツールのバージョンなど)

ruby 2.6.3, rails 5.1.6 を使用しています。
ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

attr_accessor :remember_token       # アトリビュートアクセッサー を使ってセッターメソッドとゲッターメソッドを実装することができる (データベースには反映されないけどメソッドとして使えるデータを保持する場所)

remember_tokenのあとに全角空白が混入しています。

投稿2019/07/20 04:35

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatuski_arakaki

2019/07/22 10:21

コメントありがとうございます! アトリビュートアクセッサーの後ろのコメントアウトがエラーの原因だったようです。 ありがとうございました。
asm

2019/07/22 10:23

コメントアウトの前の全角空白が問題なのでお間違えのないように 半角空白と全角空白の識別ができるテキストエディタを使った方がよいですよ
guest

0

ベストアンサー

ここですが、User.new_tokenではなくself.new_tokenではないでしょうか?

def self.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

投稿2019/07/19 09:56

bamboo-nova

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatuski_arakaki

2019/07/19 10:03

ご指摘ありがとうございます。 修正しました。 ただまだエラーが起きているようです。 ERROR["test_index_including_pagination", UsersIndexTest, 0.32258668200029206] test_index_including_pagination#UsersIndexTest (0.32s) NoMethodError: NoMethodError: undefined method `remember_token=' for #<User:0x0000000005462918> Did you mean? remember_token       = app/models/user.rb:31:in `remember' app/helpers/sessions_helper.rb:9:in `remember' app/controllers/sessions_controller.rb:14:in `create' test/test_helper.rb:27:in `log_in_as' test/integration/users_index_test.rb:10:in `block in <class:UsersIndexTest>'
bamboo-nova

2019/07/19 10:15

おそらくなのですが、self..remember_tokenのselfはUserモデルではなく、Userクラスそのものだと思います。エラーの原因はそこではないでしょうか?
tatuski_arakaki

2019/07/19 10:47

すみません。まだまだrails を始めたばかりでUserモデルではなく、Userクラスだという指摘が良く理解できません。自分でも少し調べては見たのですが良くわかりませんでした。 もう少し詳しく教えていただけますでしょうか。 もしくは理解しやすいサイトなどがあればお教えできないでしょうか。
bamboo-nova

2019/07/19 12:34

class User < ApplicationRecord ここの部分です。このクラスそのものがselfになっているのではないでしょうか。 通常は、selfがモデルそのものを意味するのですが、このモデルメソッドのプログラムでのselfは先述したクラスそのものとして解釈されているのだと思います
tatuski_arakaki

2019/07/22 10:22

コメントありがとうございます! アトリビュートアクセッサの後ろのコメントアウトがまずかったようです。 返信遅れて申し訳ありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問