设计让我将新密码更改为空

Devise let me to change new password as empty

这是我更改密码的代码:

class RegistrationsController < Devise::RegistrationsController

  protect_from_forgery

  def update_password

    if current_user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
      sign_in(current_user, bypass: true)
      redirect_to settings_path, notice: "updated"
    else
      redirect_to settings_path, alert: current_user.errors.full_messages
    end

  end

  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end

  def after_sign_up_path_for(_resource)
  end

  def after_update_path_for(_resource)
    settings_path
  end

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name])
  end
  
  private

    def user_params
      # NOTE: Using `strong_parameters` gem
      params.require(:user).permit(:current_password, :password, :password_confirmation)
    end
end

如果我输入我的当前密码并设置一个新密码,代码就可以工作,但是当我输入正确的当前密码并且作为新密码 + 确认时,我会留下空字段(空字符串)。

密码不会更改为“无密码”,但我收到一条“已更新”的闪现消息。如何防止这种情况?我能想到的是:

  if current_user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
      if params[:user][:password].blank?
        redirect_to settings_path, alert: "blank pswd"
        return
      end
      
      sign_in(current_user, bypass: true)
      redirect_to settings_path, notice: "Your password has been updated!"
    else
      redirect_to settings_path, alert: current_user.errors.full_messages
    end

但是,这个解决方案有点……难看。有没有更优雅的方式来处理这种情况?

提前致谢

阅读您的问题后,我对这种行为感到有些惊讶。但是看着 source code 我可以确认这种行为是预期的并在代码的评论中描述:

# This method also rejects the password field if it is blank (allowing
# users to change relevant information like the e-mail without changing
# their password). In case the password field is rejected, the confirmation
# is also rejected as long as it is also blank.

对于如何处理,我百感交集。我可能不会显示错误消息,因为当用户没有输入新密码时,他们可能不希望更改密码。

但是另一种处理错误消息的方法可能是根本不处理方法中的这种情况,而是使用 before_action:

before_action :ensure_new_password_provided, only: :update_password

private

  def ensure_new_password_provided
    return if params[:user][:password].present?
    redirect_to settings_path, alert: "blank pswd"
  end