密码重置期间跳过对 Devise 模型中某些成员的验证

问题描述 投票:0回答:5

我的用户(设计)模型还有姓名、城市、国家、电话成员。

在创建注册页面 - 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
ruby-on-rails validation devise
5个回答
9
投票

我遇到了类似的问题,因为创建我的用户时,并非所有字段都是必需的。使用验证来检查其他字段的存在

on: :update

这就是我解决的方法:

validates :birthdate, presence: true, on: :update, unless: Proc.new{|u| u.encrypted_password_changed? }

方法

encrypted_password_changed?
是在 Devise Recoverable 中使用的方法。


2
投票

我遇到这个问题正在寻找类似问题的答案,所以希望其他人发现这很有用。就我而言,我正在处理遗留数据,这些数据缺少以前不需要但后来变为必需的字段的信息。本质上,这就是我完成上述代码所做的事情:


validates_presence_of city, nation, phone, name, :on => :update, :if => :not_recovering_password

def not_recovering_password
  password_confirmation.nil?
end

基本上,它使用password_confirmation 字段的存在/不存在来了解用户是否正在尝试更改/重置其密码。如果未填充,他们不会更改它(因此,运行您的验证)。如果已满,则它们正在更改/重置,因此,您想跳过验证。


2
投票

在 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

0
投票

0
投票

在更改密码时不想运行的验证上添加

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
© www.soinside.com 2019 - 2024. All rights reserved.