【问题标题】:Require current password to set a new password需要当前密码才能设置新密码
【发布时间】:2015-07-23 13:15:27
【问题描述】:

我希望用户在编辑他们的个人资料时输入他们当前的密码。

这是我的用户模型的样子:

attr_accessor :current_password

def current_password
  errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
end

validate :current_password, on: :update

还有我的控制器参数:

def user_params
  params.require(:user).permit(:email, :name, :current_password, :password, :password_confirmation, :phone)
end

和用户表单部分:

<div class="form-group">
  <%= f.label :password, "Current password" %>
  <%= f.password_field :current_password, class: "form-control", placeholder: "Current password" %>
</div>

但我的堆栈级别太深,它进入了验证循环。

我做错了什么?

【问题讨论】:

    标签: ruby-on-rails ruby validation ruby-on-rails-4 grails-validation


    【解决方案1】:

    这个方法

    def current_password
      errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
    end
    

    调用自身:这就是为什么你得到堆栈太深的错误 - 它陷入了一个无休止地调用自身的循环中。

    您尝试做的事情令人困惑,因为current_password 方法正在覆盖attr_accessor :current_password 创建的方法,并且实际上进行了一些验证,而不仅仅是返回值。相反,我会这样做:

    attr_accessor :current_password
    
    validate :current_password_same_as_password, on: :update
    
    def current_password_same_as_password
      errors[:current_password] << 'Incorrect password' unless self.current_password == self.password
    end
    

    所以,在这里,我将单独留下 attr_accessor 方法:它们是简单的读写到实例变量方法的方法。验证具有不同的方法名称,因此它不会与访问器方法名称发生冲突。

    【讨论】:

    • 谢谢,菜鸟的错误。
    • 虽然逻辑不对,在on::update验证上。 self.current_password 期望与用户想要设置的新密码相同,因此它总是会失败。
    • 确实如此 - 如果配置文件编辑包括更改密码,这将不起作用。您需要考虑如何处理。
    • 您可以将新密码放入访问器中,然后使用 before_save 回调将其写入密码字段。
    【解决方案2】:

    current_password 正在调用自己。你有一个无限递归。

    你基本上是这样做的:

    def current_password
      self.current_password
    end
    

    【讨论】:

      【解决方案3】:

      正如其他答案所说,您在 current_password 中有一个无限循环。我会将验证逻辑提取到它自己的方法中。类似于以下内容。

      validate :has_correct_current_password, on: :update
      
      def has_correct_current_password
        errors[:current_password] << 'Incorrect password' unless current_password == password
      end
      

      【讨论】:

        猜你喜欢
        • 2013-03-26
        • 1970-01-01
        • 2016-05-04
        • 1970-01-01
        • 1970-01-01
        • 2011-08-29
        • 2012-11-07
        • 1970-01-01
        相关资源
        最近更新 更多