rails 4 has_secure_password呈现密码确认可选

时间:2013-07-30 18:48:20

标签: ruby-on-rails

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

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

我的测试文件如下:

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

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

3 个答案:

答案 0 :(得分: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

长篇故事

  1. docsthe source code说:

      

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

  2. 但他们也说:

      

    创建时存在密码的验证,密码确认     (使用+ password_confirmation +属性)会自动添加。如果     你希望关闭验证,传递验证:false作为     论点。如果需要,您可以手动添加更多验证。

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

  4. 我花了一些时间来吸取教训:当你感到困惑时找到源代码。这似乎是一种痛苦的方式或艰难的方式,但有时它是正确的方式。

答案 1 :(得分:5)

将测试的before行更改为:

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

那应该解决它。

这是关于什么的:

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

如果password!= password_confirmation,则会引发异常并且不会创建用户。

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

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

但对于用户创建password_confirmation 必须

答案 2 :(得分:1)

我将此作为临时措施,直到我从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