我一直在尝试为忘记密码的用户添加密码重置。用户点击忘记密码?在注册页面上。然后用户键入他们的电子邮件并单击重置密码,这会创建一个令牌并发送一封电子邮件,其中包含重置密码的链接。在大多数情况下,它仅在电子邮件框为空白或正好有 6 个随机字母/数字时有效,但当用户输入他的电子邮件并单击密码重置时它不起作用,它会显示错误消息:
**Validation failed: Password can't be blank
Password cant be blank, password is too short(6 min)**
通过更改user.rb 验证:password,presence:true,length:{ minimum: 6 } validates :password_confirmation,presence:true
我得到了不同的错误,无论如何要从这个重置密码表单中排除这个验证
app/models/user.rb:30:in `send_password_reset'
app/controllers/password_resets_controller.rb:7:in `create'
在视频 275 How I Test 中遇到此错误。11:20
失败/错误:click_button "Reset Password" ActiveRecord::RecordInvalid: 验证失败:密码不能为空,密码太短(最少为 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)>'
在 13.66 秒内完成 95 个示例,1 个失败
这是正在使用的一些代码。
用户.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
密码重置控制器.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
密码重置规范
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
# == 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