2017-01-29 11 views
1

私は大歓迎です。私は最近RoRを学び始めました。現在処理されているコースMichael Hartl私はレッスン9に行きました - クッキー。残念ながら、私は修正できないというエラーを受けました。 助けてください。NoMethodError:#<ユーザー:0x0000000a0c5698>のための未定義のメソッド `remember '

エラー:

ERROR["test_login_with_valid_information_followed_by_logout", UserLoginTest, 1.443278428982012] 
test_login_with_valid_information_followed_by_logout#UserLoginTest (1.44s) 
NoMethodError:   NoMethodError: undefined method `remember' for #<User:0x0000000a0c5698> 
     Did you mean? remember_token 
      app/helpers/sessions_helper.rb:8:in `remember' 
      app/controllers/sessions_controller.rb:10:in `create' 
      test/integration/user_login_test.rb:23:in `block in <class:UserLoginTest>' 

マイファイル:

User.rb

class User < ApplicationRecord 
    attr_accessor :remember_token 

    before_save { email.downcase! } 
    validates :name, presence: true, length: {maximum: 50} 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][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} 

    class << self 

    # Returns the hash digest of the given string. 
    def digest(string) 
     cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 
               BCrypt::Engine.cost 
     BCrypt::Password.create(string, cost: cost) 
    end 

    # Returns a random token. 
    def new_token 
     SecureRandom.urlsafe_base64 
    end 

    def remember 
     remember_token = new_token 
     update_attribute(:remember_digest, digest(remember_token)) 
    end 

    # Returns true if the given token matches the digest. 
    def authenticated?(remember_token) 
     BCrypt::Password.new(remember_digest).is_password?(remember_token) 
    end 
    end 
end 

S essions_controller.rb

class SessionsController < ApplicationController 

    def new 
    end 

    def create 
    user = User.find_by(email: params[:session][:email].downcase) 
    if user && user.authenticate(params[:session][:password]) 
     log_in user 
     remember user 
     redirect_to user 
    else 
     flash.now[:danger] = "Invalid email/password combination" 
     render 'new' 
    end 
    end 

    def destroy 
    log_out 
    redirect_to root_path 
    end 
end 

Sessions_helper.rb

module SessionsHelper 
     def log_in(user) 
     session[:user_id] = user.id 
     end 

     # Remembers a user in a persistent session. 
     def remember(user) 
     user.remember 
     cookies.permanent.signed[:user_id] = user.id 
     cookies.permanent[:remember_token] = user.remember_token 
     end 

     def current_user 
     if (user_id = session[:user_id]) 
      current_user ||= User.find_by(id: user_id) 
     elsif (user_id = cookies.signed[:user_id]) 
      user = User.find_by(id: user_id) 
      if user && user.authenticated?(cookies[:remember_token]) 
      log_in user 
      @current_user = user 
      end 
     end 
     end 

     def logged_in? 
     !current_user.nil? 
     end 

     def log_out 
     session.delete(:user_id) 
     @current_user = nil 
     end 
    end 

**user_login_test.rb** 

require 'test_helper' 

class UserLoginTest < ActionDispatch::IntegrationTest 

    def setup 
    @user = users(:marcin) 
    end 

    test "user invalid login" do 
    get login_path 
    assert_template 'sessions/new' 
    post login_path, params: { session: { email: "", password: "" } } 
    assert_template 'sessions/new' 
    assert_not flash.empty? 
    assert flash.any? 
    get root_path 
    assert_not flash.any? 
    end 

    test "login with valid information followed by logout" do 
    get login_path 
    assert_template 'sessions/new' 
    post login_path, params: { session: { email: @user.email, 
              password: 'password' } } 
    assert is_logged_in? 
    assert_redirected_to @user 
    follow_redirect! 
    assert_template 'users/show' 
    assert_select "a[href=?]", login_path, count: 0 
    assert_select "a[href=?]", logout_path 
    assert_select "a[href=?]", user_path(@user) 
    delete logout_path 
    assert_not is_logged_in? 
    assert_redirected_to root_path 
    follow_redirect! 
    skip 
    assert_select "a[href=?]", login_path 
    assert_select "a[href=?]", logout_path, count: 0 
    assert_select "a[href=?]", user_path(@user), count: 0 
    end 

end 
+0

コードを正しくフォーマットしてインデントしてください。読むのは本当に難しいです。 – spickermann

+0

test/integration/user_login_test.rbの内容を投稿する必要があります。それがエラーの原因です。おそらく、user.remember_tokenの代わりにuser.rememberと書いてあります。 –

答えて

2

問題は、あなたがそれの代わりにインスタンスメソッドのUserのクラスメソッド作り、class << selfrememberメソッドをラップしていることです。

class << selfを削除し、クラスメソッドにするメソッドの前にselfを置きます。または、rememberを移動してclass << selfの外に移動することもできます。

.... 
has_secure_password 
validates :password, presence: true, length: {minimum: 6} 

def remember 
    remember_token = new_token 
    update_attribute(:remember_digest, digest(remember_token)) 
end 
... 
+1

この回答は私の問題を解決しました。助けてくれてありがとう! – maszu

2

これは単なるclass << self宣言の外に移動することによって、方法rememberインスタンスメソッドを作成し、あなたの問題を解決する必要があります。

# frozen_string_literal: true 
class User < ApplicationRecord 
    attr_accessor :remember_token 

    before_save { email.downcase! } 
    validates :name, presence: true, length: { maximum: 50 } 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][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 remember 
    remember_token = new_token 
    update_attribute(:remember_digest, digest(remember_token)) 
    end 

    class << self 
    # Returns the hash digest of the given string. 
    def digest(string) 
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 
                BCrypt::Engine.cost 
    BCrypt::Password.create(string, cost: cost) 
    end 

    # Returns a random token. 
    def new_token 
    SecureRandom.urlsafe_base64 
    end 

    # Returns true if the given token matches the digest. 
    def authenticated?(remember_token) 
    BCrypt::Password.new(remember_digest).is_password?(remember_token) 
    end 
    end 
end 
関連する問題