我完成了Michael Hartl教程的一部分,我正在尝试将密码重置功能(从第10章)添加到我自己的应用程序中。我不想要激活功能,所以我没有添加它。但我确保添加与密码重置邮件程序相关的部分(例如,经过验证的方法)。
当我运行rake
时,这就是我得到的:
ERROR["test_password_resets", PasswordResetsTest, 2015-07-06 17:12:16 -0700]
test_password_resets#PasswordResetsTest (1436227936.11s)
NoMethodError: NoMethodError: undefined method `password_reset_expired?' for nil:NilClass
app/controllers/password_resets_controller.rb:60:in `check_expiration'
test/integration/password_resets_test.rb:26:in `block in <class:PasswordResetsTest>'
app/controllers/password_resets_controller.rb:60:in `check_expiration'
test/integration/password_resets_test.rb:26:in `block in <class:PasswordResetsTest>'
33/33: [=================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.10830s
33 tests, 83 assertions, 0 failures, 1 errors, 0 skips
这是我的密码重置控制器:
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update]
def new
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
@user.send_password_reset_email
flash[:info] = "An email was sent to " + @user.email + " with password reset instructions."
redirect_to login_url
else
flash.now[:danger] = "Hmm. We don't recognize that email. Make sure you signed up with this email."
render 'new'
end
end
def edit
end
def update
if params[:user][:password].empty?
flash.now[:danger] = "Uh oh. Your password can't be empty."
render 'edit'
elsif @user.update_attributes(user_params)
log_in @user
flash[:success] = "Success! Your password has been reset!"
redirect_to @user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
#BEFORE FILTERS
def get_user
@user = User.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
if (@user && @user.authenticated?(:reset, params[:id]))
redirect_to root_url
puts("Either I don't exist or I'm not authenticated.")
end
end
# Checks expiration of reset token.
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Uh oh! Your password reset has expired. Please request a new password reset."
redirect_to new_password_reset_url
end
end
end
这是我的用户模型:
class User < ActiveRecord::Base
attr_accessor :remember_token, :reset_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 #Set valid email regex to be used
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 }, allow_nil: true
# 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
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
#PASSWORD RESET
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
end
我已经检查了我的拼写,结束了一遍又一遍,但即使我更改了该功能的名称也没有任何区别。发生了什么事?
顺便说一句,当我实际尝试在localhost:3000中使用密码重置时,它表示已发送确认电子邮件(但我没有收到一封,因为我认为这是localhost的一部分)。然后,当我访问邮件程序预览,并使用重置密码,它工作正常。但是在生产中(在Heroku上),如果我尝试输入我的电子邮件以收到确认电子邮件,我只会得到一个错误页面--500。为什么会发生这种情况?
如果我需要添加更多详细信息,请与我们联系。
答案 0 :(得分:2)
如果找不到您的用户(例如,没有用户使用给定的电子邮件)...当您尝试检查其过期时会发生什么?
提示:查看您在valid_user
中的操作,了解您应该在check_expiration