Rails 4'has_secure_password'验证空白密码,不能执行条件验证

Dan*_*n L 6 passwords validation bcrypt ruby-on-rails-4

我知道has_secure_password在:create action上添加了password和password_confirmation的验证.

创建新用户时,必须输入密码(和确认),否则用户无效.这是预期的行为,这很好.

如果要更新用户,可以更新选择属性,而无需提交密码/确认.这也很好,因为我可以在没有密码麻烦的情况下更新用户名.

但是,我遇到了一个我想更新用户密码的情况,我要求用户输入他们当前的密码,然后输入他们的新密码和确认.问题是当我只输入当前密码并提交表单时,它会通过所有验证.即使这可能是预期的行为,我认为这是一个非常糟糕的行为,因为密码不会更改为空值,即使它通过所有验证.如果我只是假设代码实际上执行的是"说",那么用户现在应该有一个空密码.

class User < ActiveRecord::Base
  # model has password_digest field
  has_secure_password

  # has_secure_password automatically adds the following...
  # validates :password, presence: true, on: [:create]

  validates :password, length: { minimum: 8 }
end

class SettingsController < ApplicationController
  # POSTed from form with fields :current_password, :new_password, :new_password_confirmation
  def update_password
    if current_user.authenticate(params[:current_password])
      if current_user.update_attributes(password: params[:new_password], password_confirmation: params[:new_password_confirmation])
        flash.now[:notice] = "Successfully updated Password"
      else
        # Problem with new password (do nothing)
        flash.now[:error] = "Invalid new password or confirmation (nothing changed)"
        render "error"
      end
    else
      flash.now[:error] = "Must provide current password to change your password"
      render "error"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

如果您正确输入了current_password但保留了new_password和new_password_confirmation BLANK,则控制器代码会愉快地通知用户"已成功更新密码".

但是用户没有更新.密码未设置为空值.它没有改变.

我试图在密码验证上设置条件,但我的尝试似乎都不起作用.我想要做的是每次在表单中提交密码字段时验证密码的存在和长度(即使它是空白的).我用谷歌搜索了这个,我读过的所有例子都没有.

必须有一个不会破解的标准解决方案.所需的功能是每次在表单中提交密码字段,密码验证应运行并验证密码不是空白,满足最小长度要求等...

我见过很多人都说这些工作,但这些似乎都不起作用:

validates :password, length: ( minimum: 8 }, if: -> { password.present? }
validates :password, length: ( minimum: 8 }, allow_nil: true
Run Code Online (Sandbox Code Playgroud)

Bru*_*ino 0

当且仅当密码和password_confirmation 为空时,有一个验证允许密码为空。因此,如果您尝试更新密码但不发送密码确认,则会出现错误。

尝试这个:

validates :password, length: { minimum: 8 }, allow_blank: true
Run Code Online (Sandbox Code Playgroud)