rails 4 has_secure_password呈现密码确认可选

med*_*zid 6 ruby-on-rails

使用rails 4我在我的用户模型中使用has_secure_password,技巧说如果我没有设置:password_confirmation它将永远不会被触发,但为什么当我运行测试时我得到错误:密码确认不能为空如下:

Failures:

1) User 
 Failure/Error: it { should be_valid }
   expected #<User id: nil, name: "joe", email: "joe@mail.com", created_at: nil, 
   updated_at: nil, password_digest: "$2a$04$mcRr/msgYQR3kBVc3kv/m.UotBJuJuSXZKMw
   /eHTvU87..."> to be valid, but got errors: Password confirmation can't be blank
Run Code Online (Sandbox Code Playgroud)

我的测试文件看起来像:

require 'spec_helper'

describe User do

   before { @user = User.new(name: 'joe', email: 'joe@mail.com', password: 'foo') }

   subject { @user }
   #....
   #....
   describe "when password is not present" do
     before { @user.password = "" }
     it { should_not be_valid }
   end
end
Run Code Online (Sandbox Code Playgroud)

为什么我得到这个错误,有一个解决方案呢?谢谢

Chu*_*ang 21

长话短说

has_secure_password validations: false # This is the key to the solution
validates :password, presence: true, length: { minimum: 6 } # Or an length you want
Run Code Online (Sandbox Code Playgroud)

长篇故事

  1. 文档源代码,说:

    如果您不需要确认验证,则不要为password_confirmation属性设置任何值,并且不会触发验证.

  2. 但他们也说:

    将自动添加在创建时存在密码的验证,密码确认(使用+ password_confirmation +属性).如果要关闭验证,请传递验证:false作为参数.如果需要,您可以手动添加更多验证.

  3. 项目#1不是完整的描述.我们需要关闭所有验证并添加我们自己的验证规则,以使其工作如第2点所述.

我花了一些时间在这上面并得到了一个教训:当你感到困惑时找到源代码.这似乎是一种痛苦的方式或艰难的方式,但有时它是正确的方式.


Gra*_*ier 5

将测试的before行更改为:

before { @user = User.new(
  name: 'joe',
  email: 'joe@mail.com',
  password: 'foo',
  password_confirmation: 'foo')  #<== this line!
}
Run Code Online (Sandbox Code Playgroud)

那应该解决它.

这是关于:

您知道在几乎任何网站上创建新帐户时,他们会要求您输入密码并输入两次吗?这就是这个.当您创建新用户时,需要has_secure_password两次密码以确保您没有输入错误.

如果password!= password_confirmation,它将抛出异常并且不会创建用户.

同样,这仅用于用户创建.您无需在登录表单或其他任何内容中输入两个密码. 您不必将此字段添加到模型或数据库中.

如果您有一个用户创建表单,并且您不想拥有一个password_confirmation字段,那么您不必拥有.password_confirmation = password在调用save之前,您可以在控制器中进行设置.

但是对于用户创建,password_confirmation 必须存在.