设计更改密码不起作用(未知属性:current_password)

时间:2014-04-14 18:18:53

标签: ruby-on-rails devise

我不太确定我做错了什么但是当用户尝试在我的应用上更改密码时,它会给出一个错误,即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'

4 个答案:

答案 0 :(得分:11)

尝试调用由Devise提供的@user.update_attributes(account_update_params),而不是因为current_password不是数据库中的字段(至少不在默认架构中)而调用update_resource(@user, account_update_params)而导致崩溃::您继承的RegistrationsController。这又调用了由设计DatabaseAuthenticatable模块提供的resource.update_with_password(params),并在更新所有其他传递的参数之前检查current_password

然而,看起来标准的DeviseController :: RegistrationsController.update()会支持您想要的内容和更多内容(例如,如果更新需要确认电子邮件,则处理);有什么理由需要覆盖它吗?

答案 1 :(得分:6)

今天我遇到了与Ruby,Rails和Devise的以下版本相同的问题:

  • 红宝石2.4.0
  • 导轨-5.1.4
  • 设计-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 :(得分:2)

我的工作是:

编辑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'}

然后,在尝试保存更改而不确认密码的同时,我没有回复任何问题。

答案 3 :(得分:2)

从Devise 4开始,

获取&#39; current_password&#39; 的未知属性时, 无需使用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