12

I've implemented omniauth with my devise model, so I can authenticate using other services. Password is not necessary anymore for my model, as users can authenticate using twitter, facebook...

Everything is working fine, but, when an user try to edit its registration, devise skip the process because the user did not inform the 'current_password' (which doesnt exist in some cases now).

I created a registration controller to overwrite the devises one:

class RegistrationsController < Devise::RegistrationsController
  def update
    super
  end
end

But I haven't find any documentation about how to skip the password verification, how could I do it in my update action?

Tiago
  • 2,966
  • 4
  • 33
  • 41

5 Answers5

35

Similar to above, try putting this in your user model:

# bypasses Devise's requirement to re-enter current password to edit
def update_with_password(params={}) 
  if params[:password].blank? 
    params.delete(:password) 
    params.delete(:password_confirmation) if params[:password_confirmation].blank? 
  end 
  update_attributes(params) 
end
rxb
  • 690
  • 6
  • 9
  • 4
    It may be worthwhile to add a call to `clean_up_passwords`. After saving, it sets the `password` and `password_confirmation` attributes to nil to keep the user's password a secret. See Devise's [update_with_password implementation](https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb#L56) for reference. – Charles Maresh Oct 05 '12 at 17:56
  • Great Idea, Thanks. I was just thinking how to refactor and it was David Sulc's solution. Either way, I gave you both a +1 :) – Eric Wanchic Mar 01 '16 at 18:32
10

The following worked for me:

In my users controller, in the update action, I have

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

Perhaps you could adapt that to a before_save callback?

David Sulc
  • 25,946
  • 3
  • 52
  • 54
1

Even the answer has been here for a while I want to post a new one, as I think the selected answer has a little flaws. Maybe it didn't have at the moment the answer was created, but now in 2013, the answer would be like this:

The solution would be to create in User model like this:

  # bypass re-entering current password for edit
  def update_with_password(params={}) 
    current_password = params.delete(:current_password)

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

    clean_up_passwords
  end
Aleks
  • 4,866
  • 3
  • 38
  • 69
  • But what would be in the RegistrationsController#update method? – Kyle Carlson Jun 04 '13 at 17:47
  • Nothing. The registration controller shouldn't be created at all. The solution would be to create ONLY in User model like I have put in my answer and not to create any additional classes like it is said in the question. – Aleks Jun 05 '13 at 16:13
1

there is an easier answer, i do not know when devise first had this method but by just adding

Model.update_without_password(params)

it will update attributes without requiring current password.

Petros Kyriakou
  • 5,214
  • 4
  • 43
  • 82
0

As of devise v4.6.2. It is very easy to do.

As documentation said here:

By default we want to require a password checks on update. You can overwrite this method in your own RegistrationsController.

It means, in your controller override the method update_resource to replace update_with_password with update_without_password:

class Users::RegistrationsController < Devise::RegistrationsController

  # ...

  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end
end
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317