ruby-on-rails – 当密码也存在或已被更改时,Rails验证password_confirmation存在

我有以下用户模型:
class User < ActiveRecord::Base
  # Users table has the necessary password_digest field
  has_secure_password
  attr_accessible :login_name,:password,:password_confirmation

  validates :login_name,:presence=>true,:uniqueness=>true

  # I run this validation on :create so that user 
  # can edit login_name without having to enter password      
  validates :password,:length=>{:minimum=>6},:on=>:create

  # this should only run if the password has changed
  validates :password_confirmation,:if => :password_digest_changed?
end

这些验证并不像我希望的那样完成.可以执行以下操作:

# rails console
u = User.new :login_name=>"stephen"
u.valid? 
# => false
u.errors 
# => :password_digest=>["can't be blank"],# => :password=>["can't be blank","please enter at least 6 characters"]}

# so far so good,let's give it a password and a valid confirmation
u.password="password"
u.password_confirmation="password"

# at this point the record is valid and does save
u.save
# => true

# but we can Now submit a blank password from console
u.password=""
# => true
u.password_confirmation=""
# => true

u.save
# => true
# oh noes

所以我想要的是以下内容

>创建时需要密码,长度必须为6个字符
> create上需要password_confirmation,必须匹配密码
>更新login_name时,用户不必提交密码
>更新时无法删除密码

令我困惑的是,如果我使用password_changed,rails会抛出no方法错误?而不是:password_digest_changed?在我的password_confirmation验证中.我不明白为什么.

那么有谁知道我在这里做错了什么?

解决方法

密码不是数据库中的一列,对吧?只是一个属性

所以没有password_changed?方法,如果密码是列,则可用.相反,您应该检查是否设置了密码.

就像是:

validates :password_confirmation,:presence => true,:if => '!password.nil?'

虽然这解决了你遇到的最初问题,但它仍然不会完全按照你想要的那样做,因为它只是检查存在,你需要它存在并匹配密码.以下内容应该有效(与上述验证相结合).

validates :password,# you only need presence on create
          :presence => { :on => :create },# allow_nil for length (presence will handle it on create)
          :length   => { :minimum => 6,:allow_nil => true },# and use confirmation to ensure they always match
          :confirmation => true

如果您以前从未见过:确认,那么它是一个标准验证,它会查找foo和foo_confirmation,并确保它们是相同的.

请注意,您仍需要检查是否存在password_confirmation

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...