我有以下用户模型:
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