Removing Requirement for “Current Password” in Devise

I’m using the Devise gem and I wanted to only require the “Current Password” field for account updates when the password was being changed.  For other changes, I didn’t want to require the field.  This requirement was also important for me because some of my Users sign-up using Facebook.  In these cases, they might not have a password and would not be able to make any account changes.

I found my answer in this SO question and this Devise article.

First, you need a Registrations controller for your resource (in my case, the resource being used with Devise is my User model), if you don’t have one already:

in controllers:

  1. Create users/registrations_controller.rb
    Users::RegistrationsController < Devise::RegistrationsController
    
    def update
    
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    
       if resource.update_with_password(params[resource_name])
         set_flash_message :notice, :updated if is_navigational_format?
         sign_in resource_name, resource, :bypass => true
         respond_with resource, :location => after_update_path_for(resource)
       else
         clean_up_passwords(resource)
         respond_with_navigational(resource){ render_with_scope :edit }
       end
    
    end
  2. Add this to routes.rb
    devise_for :users, controllers: {registrations: 'registrations'}

Next, add new methods to your model (user.rb in my case):

#to remove the current password check if updating a profile originally gotten via oauth (fb, twitter)


  def update_with_password(params={})
    if params[:password].blank?
      params.delete(:current_password)
      self.update_without_password(params)
    else
      self.verify_password_and_update(params)
    end
  end

  def update_without_password(params={})

    params.delete(:password)
    params.delete(:password_confirmation)
    result = update_attributes(params)
    clean_up_passwords
    result
  end
  def verify_password_and_update(params)
    #devises' update_with_password 
    # https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb
    current_password = params.delete(:current_password)

    if params[:password].blank?
      params.delete(:password)
      params.delete(:password_confirmation) if params[:password_confirmation].blank?
    end

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

    clean_up_passwords
    result
  end