9

我正在尝试做两件事:

1) 更改默认的“编辑用户表单” - 随设计提供 - 删除“密码”并允许更新其他字段而无需输入密码,即删除密码的默认验证。

2) 创建一个单独的表单来更改密码

我已经完成了所有工作,只有一个问题,在更新密码的单独表格中,我包含了一个当前密码字段。使用表单时,没有对当前密码进行验证,所以我改变了

@user.update_attributes(params[:user]) 

@user.update_with_password(params[:user])

这有效,但它提出了另一个问题。回到除密码之外的所有其他详细信息的主表单,该表单现在要求输入“当前密码”。如果不对主表单上调用的当前密码进行验证,如何实现这一点?

这是我的注册控制器:

def update
  @user = User.find(current_user.id)
  if @user.update_attributes(params[:user])
    set_flash_message :notice, :updated
    # Sign in the user bypassing validation in case his password changed
    sign_in @user, :bypass => true
    redirect_to after_update_path_for(@user)
  else
    clean_up_passwords(resource)
    respond_with_navigational(resource) do
      if params[:change_password] # or flash[:change_password]
        render :change_password
      else
        render :edit
      end
    end
  end
end

谢谢!

解决方案 1

我找到了解决问题的方法(尽管很混乱):

def update
  @user = User.find(current_user.id)

  if params[:user][:password].blank?
    if @user.update_attributes(params[:user])
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case his password changed
      sign_in @user, :bypass => true
      redirect_to after_update_path_for(@user)
    else
      respond_with_navigational(resource) do
        render :edit
      end
    end
  else
    if @user.update_with_password(params[:user])
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case his password changed
      sign_in @user, :bypass => true
      redirect_to after_update_path_for(@user)
    else
      clean_up_passwords(resource)
      respond_with_navigational(resource) do
        render :change_password
      end
    end
  end

解决方案 2

您能提出更好的解决方案吗?

4

2 回答 2

6

接受的答案并没有完全解决这个问题。其中,我相信对于用户个人资料属性(如电子邮件、名字等)与密码有一个单独的表格。这是你需要做的:

首先,利用 Devise::RegistrationsController 进行个人资料更新。

  • 自定义视图并删除passwordpassword_confirmation字段。如果看跌期权中不存在这些,设计将忽略它们。
  • 如果您不想要求当前密码来更改配置文件,请阅读此内容。不建议; 不安全。

其次,创建您自己的控制器来管理密码更新,并创建您自己的助手来要求current_password、、passwordpassword_confirmation更新。

class PasswordsController < ApplicationController
  before_filter :authenticate_user!

  def edit
    @user = current_user
  end

  def update
    @user = User.find(current_user.id)
    if @user.update_password_with_password(user_params)
      # Sign in the user by passing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to edit_password_path, flash: { success: "Successfully updated password" }
    else
      render "edit"
    end

  end

  private

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

end

这是助手,update_password_with_password它将需要新的密码字段。

class User < ActiveRecord::Base
  def update_password_with_password(params, *options)
    current_password = params.delete(:current_password)

    result = if valid_password?(current_password)
               update_attributes(params, *options)
             else
               self.assign_attributes(params, *options)
               self.valid?
               self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
               false
             end

    clean_up_passwords
    result
  end
end
于 2015-08-08T03:20:29.573 回答
5

您是否费心查看 Devise wiki?这两种情况都有例子

  1. https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password
  2. https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password

你应该看看@user.update_with_password(params[:user])vs@user.update_attributes(params[:user])

于 2013-07-11T06:10:49.863 回答