我的用户(设计)模型还有姓名、城市、国家、电话成员。
在创建注册页面 - I
validates_presence_of city, nation, phone, name, email, :on => :create
在编辑注册页面 - I
validates_presence_of city, nation, phone, name, :on => :update
现在,当我在忘记密码页面上设置新密码时,它会要求输入城市、国家、电话、姓名
Devise::PasswordsController#update
如何处理选择性验证?
我猜应该是这样的,
validates_presence_of city, nation, phone, name, :on => :update, :if => :not_recovering_password
def not_recovering_password
# what goes here
end
我遇到了类似的问题,因为创建我的用户时,并非所有字段都是必需的。使用验证来检查其他字段的存在
on: :update
。
这就是我解决的方法:
validates :birthdate, presence: true, on: :update, unless: Proc.new{|u| u.encrypted_password_changed? }
方法
encrypted_password_changed?
是在 Devise Recoverable 中使用的方法。
我遇到这个问题正在寻找类似问题的答案,所以希望其他人发现这很有用。就我而言,我正在处理遗留数据,这些数据缺少以前不需要但后来变为必需的字段的信息。本质上,这就是我完成上述代码所做的事情:
validates_presence_of city, nation, phone, name, :on => :update, :if => :not_recovering_password
def not_recovering_password
password_confirmation.nil?
end
基本上,它使用password_confirmation 字段的存在/不存在来了解用户是否正在尝试更改/重置其密码。如果未填充,他们不会更改它(因此,运行您的验证)。如果已满,则它们正在更改/重置,因此,您想跳过验证。
在 Devise 模型中,您可以覆盖
reset_password!
并使用您自己的验证。例如:
def reset_password!(new_password, new_password_confirmation)
self.password = new_password
self.password_confirmation = new_password_confirmation
validates_presence_of :password
validates_confirmation_of :password
validates_length_of :password, within: Devise.password_length, allow_blank: true
if errors.empty?
clear_reset_password_token
after_password_reset
save(validate: false)
end
end
在更改密码时不想运行的验证上添加
unless: "encrypted_password_changed?"
或 if: "password_confirmation.nil?"
不是解决方案,因为这不会在使用以下命令更新整个 User
对象(某些属性和密码)时运行验证/user/edit 表单。
在您的 User
类(或您使用 Devise 的任何模型)中重写 Devise 方法
reset_password会更可靠,这样只考虑密码和 password_confirmation 验证。
class User < ApplicationRecord
def reset_password(new_password, new_password_confirmation)
if new_password.present?
self.password = new_password
self.password_confirmation = new_password_confirmation
return true if save
password_valid = (errors.messages.keys & [:password, :password_confirmation]).blank?
if password_valid
errors.clear
save(validate: false)
end
else
errors.add(:password, :blank)
false
end
end
end