#<User:0x0000010b454f50> 的未定义方法 `remember_token='
undefined method `remember_token=' for #<User:0x0000010b454f50>
我正在完成 Rails 教程,但卡在了第 8 章 -- 关于登录会话的内容。当我提交应该创建新会话的 email/pw 组合时出现错误。
这是错误:
NoMethodError in SessionsController#create
undefined method `remember_token=' for #<User:0x0000010b454f50>
Extracted source (around line #435):
else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end
从那里我在会话控制器中查看创建。然后我尝试查看调用 remember_token 方法的位置。
会话控制器:
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
#if 1 then remember, else forget
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
#call log_out helper method
log_out if logged_in?
redirect_to root_url
end
end
我打电话给remember
,这看起来很重要。这是会话助手:
module SessionsHelper
#Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
def remember(user)
#generate a new token and provide the encrypted hash
user.remember
cookies.permanent.signed[:user_id]=user.id
cookies.permanent[:remember_token]=user.remember_token
end
def current_user
#if session user id exists, then set to user_id and then...
if (user_id = session[:user_id])
#set @current_user to the correct user account
@current_user||= User.find_by(id: user_id)
#else, if signed cookie user id exists, set to user_id and then...
elsif (user_id = cookies.signed[:user_id])
#set user to the correct user account and...
user = User.find_by(id: user_id)
#if user is authenticated, then log them in and set @current_user to user
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
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
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
end
这看起来像钥匙 -- cookies.permanent[:remember_token]=user.remember_token
。
但是我不知道如何定义remember_token方法。当我浏览教程时,我没有看到任何描述 remember_token 的方法。我得到的最接近的是在用户模型中(称为 remember
的方法):
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
belongs_to :courses
belongs_to :lessons
validates :first_name, presence: true, length: { maximum: 50 }
validates :last_name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 },
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::Password.create(string, cost: cost)
BCrypt::Password.create(string, cost: cost)
end
#Returns a random token
def User.new_token
SecureRandom.urlsafe_base64
end
#creates a new token (random string) then encypts it by returning a hash
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
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
#forgets a user
def forget
update_attribute(:remember_digest, nil)
end
end
我是否理解会话控制器、会话助手和用户模型之间的相互作用?相互作用设置不正确 - 这会引发错误吗?我不明白为什么它不起作用...
背景:
作为一项安全功能,本教程有意避免将 remember_token 放入数据库中。所以这不是问题。
问题出在会话控制器中——我不理解三元运算符,因此重复了一些它的功能。这是原始的创建方法:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
#if 1 then remember, else forget
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
这个位 remember user
是多余的。
三进制params[:session][:remember_me] == '1' ? remember(user) : forget(user)
表示如果params[:session][:remember_me]
为1,则remember(user)
否则forget(user)
。
然后调用 remember user
(与 remember(user)
相同)我执行了两次相同的操作,导致了错误。
我正在完成 Rails 教程,但卡在了第 8 章 -- 关于登录会话的内容。当我提交应该创建新会话的 email/pw 组合时出现错误。
这是错误:
NoMethodError in SessionsController#create
undefined method `remember_token=' for #<User:0x0000010b454f50>
Extracted source (around line #435):
else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end
从那里我在会话控制器中查看创建。然后我尝试查看调用 remember_token 方法的位置。
会话控制器:
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
#if 1 then remember, else forget
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
#call log_out helper method
log_out if logged_in?
redirect_to root_url
end
end
我打电话给remember
,这看起来很重要。这是会话助手:
module SessionsHelper
#Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
def remember(user)
#generate a new token and provide the encrypted hash
user.remember
cookies.permanent.signed[:user_id]=user.id
cookies.permanent[:remember_token]=user.remember_token
end
def current_user
#if session user id exists, then set to user_id and then...
if (user_id = session[:user_id])
#set @current_user to the correct user account
@current_user||= User.find_by(id: user_id)
#else, if signed cookie user id exists, set to user_id and then...
elsif (user_id = cookies.signed[:user_id])
#set user to the correct user account and...
user = User.find_by(id: user_id)
#if user is authenticated, then log them in and set @current_user to user
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
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
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
end
这看起来像钥匙 -- cookies.permanent[:remember_token]=user.remember_token
。
但是我不知道如何定义remember_token方法。当我浏览教程时,我没有看到任何描述 remember_token 的方法。我得到的最接近的是在用户模型中(称为 remember
的方法):
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
belongs_to :courses
belongs_to :lessons
validates :first_name, presence: true, length: { maximum: 50 }
validates :last_name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 },
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::Password.create(string, cost: cost)
BCrypt::Password.create(string, cost: cost)
end
#Returns a random token
def User.new_token
SecureRandom.urlsafe_base64
end
#creates a new token (random string) then encypts it by returning a hash
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
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
#forgets a user
def forget
update_attribute(:remember_digest, nil)
end
end
我是否理解会话控制器、会话助手和用户模型之间的相互作用?相互作用设置不正确 - 这会引发错误吗?我不明白为什么它不起作用...
背景: 作为一项安全功能,本教程有意避免将 remember_token 放入数据库中。所以这不是问题。
问题出在会话控制器中——我不理解三元运算符,因此重复了一些它的功能。这是原始的创建方法:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
#if 1 then remember, else forget
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
remember user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
这个位 remember user
是多余的。
三进制params[:session][:remember_me] == '1' ? remember(user) : forget(user)
表示如果params[:session][:remember_me]
为1,则remember(user)
否则forget(user)
。
然后调用 remember user
(与 remember(user)
相同)我执行了两次相同的操作,导致了错误。