I've been trying to add a password reset for users that forget their password. The users click on forgot password? on the sign up page. Then the user types their email and clicks reset password, which creates a token and sends an email with a link to reset their password. For the most part it works ONLY when the email box is blank or has exactly 6 random letter/numbers, but it doesn't work when a user puts in his email and clicks password reset, it brings up the error message:
我一直在尝试为忘记密码的用户添加密码重置。用户点击忘记密码?在注册页面上。然后用户输入他们的电子邮件并单击reset password,该密码创建一个令牌并发送带有链接的电子邮件来重置密码。大多数情况下,它只在电子邮件框为空或者有6个随机字母/数字时有效,但当用户输入电子邮件并单击“重置密码”时,它就不起作用了。
**Validation failed: Password can't be blank
Password cant be blank, password is too short(6 min)**
By changing user.rb validates :password, presence: true, length: { minimum: 6 } validates :password_confirmation, presence: true
通过改变用户。rb验证:密码,存在:true, length:{最小:6}验证:password_confirm, presence: true。
I have gotten different errors, is there anyway to exclude this validation from this Reset Password form
我得到了不同的错误,是否有从这个重置密码表单中排除这个验证
app/models/user.rb:30:in `send_password_reset'
app/controllers/password_resets_controller.rb:7:in `create'
Ran into this error in video 275 How I Test. on 11:20
在视频275 How I中遇到了这个错误。在11:20
Failure/Error: click_button "Reset Password" ActiveRecord::RecordInvalid: Validation failed: Password can't be blank, Password is too short (minimum is 6 characters), Password confirmation can't be blank
失败/错误:click_button“Reset Password”ActiveRecord::记录无效:验证失败:密码不能为空,密码太短(最少为6个字符),密码确认不能为空
# ./app/models/user.rb:30:in `send_password_reset'
# ./app/controllers/password_resets_controller.rb:7:in `create'
# (eval):2:in `click_button'
# ./spec/requests/password_resets_spec.rb:9:in `block (2 levels) in <top (required)>'
Finished in 13.66 seconds 95 examples, 1 failure
完成时间为13.66秒95个例子,失败1次
This is some of the code being used.
这是正在使用的一些代码。
user.rb
user.rb
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
before_save { |user| user.email = email.downcase }
before_save :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
password_resets_controller.rb
password_resets_controller.rb
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
user.send_password_reset
redirect_to root_url, :notice => "Email sent with password reset instructions."
end
def edit
@user = User.find_by_password_reset_token!(params[:id])
end
end
password_resets_spec
password_resets_spec
require 'spec_helper'
describe "PasswordResets" do
it "emails user when requesting password reset" do
user = Factory(:user)
visit signin_path
click_link "password"
fill_in "Email", :with => user.email
click_button "Reset Password"
current_path.should eq(root_path)
page.should have_content("Email sent")
last_email.to.should include(user.email)
end
end
user_spec.rb
user_spec.rb
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
require 'spec_helper'
describe User do
describe "#send_password_reset" do
let(:user) { Factory(:user) }
it "generates a unique password_reset_token each time" do
user.send_password_reset
last_token = user.password_reset_token
user.send_password_reset
user.password_reset_token.should_not eq(last_token)
end
it "saves the time the password reset was sent" do
user.send_password_reset
user.reload.password_reset_sent_at.should be_present
end
it "delivers email to user" do
user.send_password_reset
last_email.to.should include(user.email)
end
end
before do
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { @user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:remember_token) }
it { should respond_to(:authenticate) }
it { should respond_to(:admin) }
it { should respond_to(:authenticate) }
it { should be_valid }
it { should_not be_admin }
describe "with admin attribute set to 'true'" do
before { @user.toggle!(:admin) }
it { should be_admin }
end
describe "when name is not present" do
before { @user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { @user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { @user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user@foo,com user_at_foo.org example.user@foo.
foo@bar_baz.com foo@bar+baz.com]
addresses.each do |invalid_address|
@user.email = invalid_address
@user.should_not be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
addresses.each do |valid_address|
@user.email = valid_address
@user.should be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = @user.dup
user_with_same_email.email = @user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "email address with mixed case" do
let(:mixed_case_email) { "Foo@ExAMPle.CoM" }
it "should be saved as all lower-case" do
@user.email = mixed_case_email
@user.save
@user.reload.email.should == mixed_case_email.downcase
end
end
describe "when password is not present" do
before { @user.password = @user.password_confirmation = " " }
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { @user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "when password confirmation is nil" do
before { @user.password_confirmation = nil }
it { should_not be_valid }
end
it { should respond_to(:authenticate) }
describe "with a password that's too short" do
before { @user.password = @user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { @user.save }
let(:found_user) { User.find_by_email(@user.email) }
describe "with valid password" do
it { should == found_user.authenticate(@user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end
describe "remember token" do
before { @user.save }
its(:remember_token) { should_not be_blank }
end
end
2 个解决方案
#1
0
At first glance, when resetting the password your code is trying to save a blank password (hence your error). Try debugging it one line at a time using logger.debug
to try and find at what point your code nullifies the password before saving it. I haven't used the UserMailer, but it looks like the error is with the UserMailer.password_reset(self).deliver
line. If you wrote the method, I'd look at debugging that first. If it was automated, try and debug the sections that set all the parameters for the mailer to generate the token and reset your password.
乍一看,当重新设置密码时,您的代码试图保存一个空白密码(因此会出现错误)。尝试使用logger.debug每次调试一行,尝试在保存密码之前找出密码在什么地方无效。我还没有使用UserMailer,但是看起来错误出现在usermail .password_reset(self). delivery line上。如果您编写这个方法,我将首先调试它。如果是自动的,请尝试并调试设置邮件发送者所有参数的部分,以生成令牌并重置密码。
Hope this helps.
希望这个有帮助。
#2
2
In your send_password_reset method you're using:
在您正在使用的send_password_reset方法中:
save!
use instead
而不是使用
save!(validate: false)
and everything will work. The problem is that you're attempting to save the model and validations are interfering. You don't need to validate anything in the send_password_reset method since there is nothing generated from the user, so there's no danger of invalid information being saved to the database.
和一切工作。问题是您正在尝试保存模型,而验证正在进行干扰。您不需要在send_password_reset方法中验证任何内容,因为用户没有生成任何内容,因此不存在将无效信息保存到数据库的危险。
#1
0
At first glance, when resetting the password your code is trying to save a blank password (hence your error). Try debugging it one line at a time using logger.debug
to try and find at what point your code nullifies the password before saving it. I haven't used the UserMailer, but it looks like the error is with the UserMailer.password_reset(self).deliver
line. If you wrote the method, I'd look at debugging that first. If it was automated, try and debug the sections that set all the parameters for the mailer to generate the token and reset your password.
乍一看,当重新设置密码时,您的代码试图保存一个空白密码(因此会出现错误)。尝试使用logger.debug每次调试一行,尝试在保存密码之前找出密码在什么地方无效。我还没有使用UserMailer,但是看起来错误出现在usermail .password_reset(self). delivery line上。如果您编写这个方法,我将首先调试它。如果是自动的,请尝试并调试设置邮件发送者所有参数的部分,以生成令牌并重置密码。
Hope this helps.
希望这个有帮助。
#2
2
In your send_password_reset method you're using:
在您正在使用的send_password_reset方法中:
save!
use instead
而不是使用
save!(validate: false)
and everything will work. The problem is that you're attempting to save the model and validations are interfering. You don't need to validate anything in the send_password_reset method since there is nothing generated from the user, so there's no danger of invalid information being saved to the database.
和一切工作。问题是您正在尝试保存模型,而验证正在进行干扰。您不需要在send_password_reset方法中验证任何内容,因为用户没有生成任何内容,因此不存在将无效信息保存到数据库的危险。