【问题标题】:How to separate change password from devise form如何将更改密码与设计表格分开
【发布时间】:2013-07-11 04:08:42
【问题描述】:

我正在尝试做两件事:

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

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

【问题讨论】:

    标签: ruby-on-rails forms devise change-password


    【解决方案1】:

    接受的答案并未完全解决问题。其中,我相信对于用户个人资料属性(如电子邮件、名字等)与密码有一个单独的表格。为此,您需要执行以下操作:

    首先,利用 Devise::RegistrationsController 更新您的个人资料。

    • 自定义视图并删除passwordpassword_confirmation 字段。如果 put 中不存在这些,Devise 会忽略它们。
    • 如果您不想要求当前密码来更改配置文件,read this。不建议;不安全。

    其次,创建您自己的控制器来管理密码更新,并创建您自己的助手以在更新时要求 current_passwordpasswordpassword_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
    

    【讨论】:

    • 我正在尝试遵循这个答案,不过我有点菜鸟,您能否添加应该与此解决方案一起使用的路线、视图和链接到?谢谢!
    【解决方案2】:

    您是否费心查看 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])@user.update_attributes(params[:user])

    【讨论】:

    • 是的,我都看过了,我看不出它们在哪里提供了解决问题的方法?能具体给我看看吗?
    • 复制并粘贴我的回答:您应该查看 @user.update_with_password(params[:user]) 与 @user.update_attributes(params[:user])
    • 你能看看我对上述问题所做的编辑吗^^ 它有效,但这是最好的方法吗?
    • 如果密码哈希键不存在,您为什么要尝试删除它? (前 4 行)。并且 - 密码更改和其他代码的其余部分是否相同?
    • 有很多重复的代码,我能想到的一种解决方案是update_result = ( params[:user][:password].blank? ? @user.update_attributes(params[:user]) : @user.update_with_password(params[:user]) ),然后检查是否为 false(这是两个更新不同的部分),但这很难看。
    猜你喜欢
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2014-09-28
    • 2015-12-19
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多