Devise 3 (rails 4) can't update user without password

前端 未结 7 1112
萌比男神i
萌比男神i 2021-02-06 00:34

I\'m trying to update a user without having to provide a password, but approaches that worked on older devise/rails versions no longer work with devise 3 and rails 4 strong para

相关标签:
7条回答
  • 2021-02-06 01:21

    You can use @user.update_without_password(user_params) method to update your other fields.

    For example, I have this in my custom users_controller.rb. I update with remote call (ajax).

    #users_controller.rb
    
    def update
      respond_to do |format|
        if needs_password?(@user, user_params)
          if @user.update_with_password(user_params_password_update)
            flash[:success] = 'User was successfully updated. Password was successfully updated'
            format.js {render 'update'}
          else
            error = true
          end
        else
          if @user.update_without_password(user_params)
            flash[:success] = 'User was successfully updated.'
            format.js {render 'update'}
          else
            error = true
          end
        end
    
        if error
          flash[:error] = @user.errors.full_messages.join(', ')
          format.js {render json: @user.errors.full_messages, status: :unprocessable_entity}
        end
      end
    end
    
    private
    
    def needs_password?(user, user_params)
      !user_params[:password].blank?
    end
    
    def user_params
      params[:user].permit(:email, :password, :password_confirmation, :username, :full_name)
    end
    
    #Need :current_password for password update
    def user_params_password_update
      params[:user].permit(:email, :password, :password_confirmation, :current_password, :username, :full_name)
    end
    
    0 讨论(0)
  • 2021-02-06 01:21

    simply override the Devise by creating app/controller/registrations_controller.rb

    class RegistrationsController < Devise::RegistrationsController
    
      protected
      def update_resource(resource, params)
        resource.update(params.except(:current_password))
      end
    end
    

    this code will directly update user params except :current_password

    and update config/routes.rb

    devise_for :users, controllers: {registrations: 'registrations'}
    
    0 讨论(0)
  • 2021-02-06 01:22

    The key is in this "user_params[:password].blank?". The next is a example of the code:

    def update
      if user_params[:password].blank?
        params = user_params_without_password
      else
        params = user_params
      end
    
      respond_to do |format|
        if @user.update(params)
          format.html { redirect_to @user, notice: t(:user_update) }
          format.json { render :show, status: :ok, location: @user }
        else
          format.html { render :edit }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end
    
    private
    
    def set_user
      @user = User.find(params[:id])
    end
    
    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user).permit(:email, :username, :first_name, :last_name, :admin, :locked, :password)
    end
    
    def user_params_without_password
      params.require(:user).permit(:email, :username, :first_name, :last_name, :admin, :locked)
    end
    

    Hope you help

    0 讨论(0)
  • 2021-02-06 01:23

    The password validation is coming from the user model:

    validates :password, presence: true
    

    The solution is to only validate presence on create and allow_blank on update:

    validates :password, presence: true, length: {minimum: 5, maximum: 120}, on: :create
    validates :password, length: {minimum: 5, maximum: 120}, on: :update, allow_blank: true
    
    0 讨论(0)
  • 2021-02-06 01:29

    I went round in circles on this for ages. The answers are all in validatable as suggested by mrstif above. If you use the validatable module Devise works out of the box (with configuration options) allowing you to update user details without supplying a password so be very careful about rolling your own password validations.

    0 讨论(0)
  • 2021-02-06 01:33

    As of 2014, you can simply override a protected method and do:

    class RegistrationsController < Devise::RegistrationsController
    
      protected
    
      def update_resource(resource, params)
        resource.update_without_password(params)
      end
    end
    
    0 讨论(0)
提交回复
热议问题