我不确定如何最好地解决这个问题 - 我需要在添加新记录时验证用户的密码,我还需要能够在更新passoword时进行验证。但是,如何让用户只更新其个人资料的一部分,并可能将密码留空。
在你建议allow_blank之前注意我知道这个选项但这不合适,因为当用户因丢失/遗忘而需要更改密码时我不想允许用户有一个空密码。
答案 0 :(得分:1)
您可以将if语句传递给验证:
`validates_presence_of:password,:if => :should_validate_password
您应该能够在此处传递条件以捕获用户是否正在更新其密码:
<强>模型强>
def should_validate_password?
updating_password || new_record?
end
<强>控制器强>
@user.updating_password = true
@user.save
请点击此处了解详情:http://railscasts.com/episodes/41-conditional-validations
<强>更新强>
在你的情况下,我会在控制器中创建一个if语句,检测是否在params中传递了任何新密码。如果是这样,我会设置@user.updating_password = true
,这将触发模型中的验证。如果没有,则@user.updating_password
将为零,并且不会触发验证。
答案 1 :(得分:1)
通常,#password=
和#password_confirmation=
只是虚拟设置者,true属性为#hashed_password
或其他。所以,你可以这样做:
class User
attr_accessor :password, :password_confirmation
validate :validates_password
validates_presence_of :hashed_password
private
def validates_password
if password or password_confirmation
if password != password_confirmation
errors.add( :password, 'your message' )
end
# your others validations
self.hashed_password = hash_password
end
end
def hash_password
# your hashing code
end
end
创建提供密码的用户时,会设置虚拟属性password
和password_confirmation
,因此if
条件为真,并且会强制执行验证。
如果已设置密码且用户未更改密码(不提供密码的编辑表单),则不会强制执行验证,因为if password and password_confirmation
。
当密码已设置且用户更改密码时,password
和password_confirmation
已设置,因此会触发验证。
如果您想重置密码,只需将操作hashed_password
设置为nil即可。由于validates_presence_of :hashed_password
,模型现在无效,用户必须提供新模型。
使用#has_secure_password
,rails将处理大部分内容,尤其是:
所以,您需要的只是添加自己的验证,只有在password
或password_confirmation
出现时才会这样做。
class User
has_secure_password
validate :validates_password
private
def validates_password
if password or password_confirmation
unless <your_test>
errors.add( :password, '<your error message>' )
end
end
end
end
如前所述,只有在提供password和password_confirmation时才会触发此操作,只有当用户将其作为表单数据提交时才会触发(实际属性为password_digest
)。
答案 2 :(得分:1)
validates :password, presence: true, if: lambda { |user| user.password_changed? }
by ActiveModel :: Dirty(默认情况下适用于所有型号)