为什么我的方法没有被定义?

时间:2014-12-27 21:51:39

标签: ruby-on-rails ruby

我收到以下错误。我是编程新手,我理解这是一个没有定义摘要方法的问题。但是,在我的用户方法中,它被定义为User.Digest(字符串)。希望有人可以向我发送正确的方向来帮助解决这个问题。

错误1

ERROR["test_current_user_returns_nil_when_remember_digest_is_wrong", SessionsHelperTest,   0.722231]
test_current_user_returns_nil_when_remember_digest_is_wrong#SessionsHelperTest (0.72s)
NoMethodError:         NoMethodError: undefined method `digest' for true:TrueClass
        app/models/user.rb:38:in `authenticated?'
        app/helpers/sessions_helper.rb:21:in `current_user'
        test/helpers/sessions_helper_test.rb:17:in `block in <class:SessionsHelperTest>'
    app/models/user.rb:38:in `authenticated?'
    app/helpers/sessions_helper.rb:21:in `current_user'
    test/helpers/sessions_helper_test.rb:17:in `block in <class:SessionsHelperTest>'

错误2

ERROR["test_current_user_returns_right_user_when_session_is_nil", SessionsHelperTest, 0.736168]
 test_current_user_returns_right_user_when_session_is_nil#SessionsHelperTest (0.74s)
NoMethodError:         NoMethodError: undefined method `digest' for true:TrueClass
        app/models/user.rb:38:in `authenticated?'
        app/helpers/sessions_helper.rb:21:in `current_user'
        test/helpers/sessions_helper_test.rb:11:in `block in <class:SessionsHelperTest>'
    app/models/user.rb:38:in `authenticated?'
    app/helpers/sessions_helper.rb:21:in `current_user'
    test/helpers/sessions_helper_test.rb:11:in `block in <class:SessionsHelperTest>'

SessionsHelperTest

require 'test_helper'

class SessionsHelperTest < ActionView::TestCase

 def setup
  @user = users(:kyle)
  remember(@user)
 end

 test "current_user returns right user when session is nil" do
  assert_equal @user, current_user
  assert is_logged_in?
 end

 test "current_user returns nil when remember digest is wrong" do
  @user.update_attribute(:remember_digest, User.digest(User.new_token))
  assert_nil current_user
 end
end

用户方法

class User < ActiveRecord::Base
 attr_accessor :remember_token
 before_save { email.downcase! }
 validates :name, presence: true, length: { maximum: 50 }
 VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[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, length: { minimum: 6 }

# Returns the hash digest of the given string. 
 def User.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 User.new_token
    SecureRandom.urlsafe_base64
 end

#Remembers a user in the database for use in persistent sessions 
 def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
 end

# Forgets a user. 
 def forget
    update_attribute(:remember_digest, nil)
 end

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

模块SessionsHelper

# Logs in the given user.
 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

#Returns the user corresponding to the remember token cookie.
  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

#Returns true if the user is logged in, false otherwise. 
 def logged_in?
    !current_user.nil? 
 end

    # Forgets a persistent session.
 def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
 end

# Logs out the current user.
 def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
 end
 end

1 个答案:

答案 0 :(得分:2)

您正在调用remember.digestremember是一个返回布尔true的方法,因此出现错误消息:

  

NoMethodError:未定义的方法`digest'表示true:TrueClass

鉴于上下文中的代码......

return false if remember_digest.nil?
BCrypt::Password.new(remember.digest).is_password?(remember_token)

......很明显第二行应该使用remember_digest,而不是remember.digest

BCrypt::Password.new(remember_digest).is_password?(remember_token)
                             |
    underscore, not period --'