【问题标题】:devise change password not working (unknown attribute: current_password)设计更改密码不起作用(未知属性:current_password)
【发布时间】:2014-05-28 20:07:13
【问题描述】:

我不太确定自己做错了什么,但是当用户尝试在我的应用程序上更改他们的密码时,它会给出一个错误,即 current_password 是一个未知属性。

这是我的代码:

def configure_devise_permitted_parameters
  registration_params = [:email, :password, :password_confirmation, :first_name, :last_name]

  if params[:action] == 'update'
    devise_parameter_sanitizer.for(:user_update) {
      |u| u.permit(registration_params << :current_password)
    }
  elsif params[:action] == 'create'
    devise_parameter_sanitizer.for(:sign_up) {
      |u| u.permit(registration_params)
    }
  end
end

class RegistrationsController < Devise::RegistrationsController
  def update
    account_update_params = devise_parameter_sanitizer.sanitize(:user_update)

    if account_update_params[:password].blank?
      account_update_params.delete("password")
      account_update_params.delete("password_confirmation")
      account_update_params.delete("current_password")
    end

    @user = User.find(current_user.id)
    if @user.update_attributes(account_update_params)
      set_flash_message :notice, :updated
      sign_in @user, bypass: true
      redirect_to after_update_path_for(@user)
    else
      render "edit"
    end
  end

我在这里做错了什么?在正确保存新密码之前,我应该如何处理 current_password 以检查它是否正确?

编辑:堆栈跟踪

activerecord (4.0.3) lib/active_record/attribute_assignment.rb:47:in `rescue in _assign_attribute'
activerecord (4.0.3) lib/active_record/attribute_assignment.rb:42:in `_assign_attribute'
activerecord (4.0.3) lib/active_record/attribute_assignment.rb:29:in `block in assign_attributes'
activerecord (4.0.3) lib/active_record/attribute_assignment.rb:23:in `each'
activerecord (4.0.3) lib/active_record/attribute_assignment.rb:23:in `assign_attributes'

【问题讨论】:

  • 你到底在哪里得到错误?你能分享错误堆栈跟踪吗?
  • 在线获取错误:@user.update_atributes(account_update_params)。

标签: ruby-on-rails devise


【解决方案1】:

我今天在使用以下版本的 Ruby、Rails 和 Devise 时遇到了同样的问题:

  • ruby-2.4.0
  • rails-5.1.4
  • devise-4.3.0

这是我的解决方案:

app/controllers/registrations_controller.rb 中创建您的注册控制器

class RegistrationsController < Devise::RegistrationsController

  protected

  def update_resource(resource, params)
    # Require current password if user is trying to change password.
    return super if params["password"]&.present?

    # Allows user to update registration information without password.
    resource.update_without_password(params.except("current_password"))
  end
end

告诉 Devise 您使用在 app/controllers/registrations_controller.rb 中定义的注册控制器。

# config/routes.rb
devise_for :users, controllers: { registrations: "registrations" }

【讨论】:

    【解决方案2】:

    从设计 4 开始,

    当获取“current_password”的未知属性时, 无需玩devise_parameter_sanitizer

    进入 app/controllers/registrations_controller.rb

    改变

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

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

    【讨论】:

      【解决方案3】:

      它对我有用的是:

      编辑 app/controllers/application_controller.rb

      并添加以下代码

      protected
      
      def configure_permitted_parameters
        devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :password_confirmation) }
      end
      

      编辑 /app/controllers/users/registrations_controller.rb

      并添加以下代码

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

      并添加以下路线

      devise_for :users, controllers: {registrations: 'registrations'}
      

      然后,在不确认密码的情况下尝试保存更改时,我没有返回任何问题。

      【讨论】:

        【解决方案4】:

        不要调用 @user.update_attributes(account_update_params),因为 current_password 不是数据库中的字段(至少不是默认模式),而是调用 update_resource(@user, account_update_params),它由您提供的 Devise::RegistrationsController 提供重新继承自。这反过来调用了由设计的DatabaseAuthenticatable 模块提供的resource.update_with_password(params) 并在更新所有其他传递的参数之前检查current_password

        但是,标准的 DeviseController::RegistrationsController.update() 似乎会支持您想要的以及更多功能(例如,如果更新需要确认电子邮件,则进行处理);有什么理由需要覆盖它吗?

        【讨论】:

          猜你喜欢
          • 2017-10-13
          • 2013-11-08
          • 2012-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-04
          • 1970-01-01
          • 2017-08-26
          相关资源
          最近更新 更多