rails 4 has_secure_password呈现密码确认可选

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

Failures: 1) User Failure/Error: it { should be_valid } expected # to be valid, but got errors: Password confirmation can't be blank 

我的测试文件看起来像:

 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 

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

在测试before将测试更改为:

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

那应该解决它。

这是关于:

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

如果password != password_confirmation ,它将抛出exception并且不会创建用户。

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

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

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

长话短说

 has_secure_password validations: false # This is the key to the solution validates :password, presence: true, length: { minimum: 6 } # Or an length you want 

长篇故事

  1. 文档和源代码说:

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

  2. 但他们也说:

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

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

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

我做这个作为一个临时措施,直到我从Rails 4.0.13到4.1及更高版本获得此应用程序:

 class User < ActiveRecord::Base has_secure_password # Tempfix until Rails 4.1 https://github.com/rails/rails/pull/11107#issuecomment-21850919 raise "Get rid of this on Rails 4.1+" if Rails::VERSION::STRING != "4.0.13" before_validation { self.password_confirmation ||= password } end