Last Updated: May 15, 2019
·
7.625K
· ireneuszskrobis

Ignore (turn off) Devise config.reconfirmable while saving email in update action

When you set config.reconfirmable = true in config/initializers/devise.rb than Devise requires any email changes to be confirmed by email. This might be a problem when you want to change email without sending confirmation, for example when admin edits some user.

I found a few old solutions like user.send(:update_without_callbacks) or user.save(:validate => false). But they actually don’t work (former in Rails 3, latter at all). So this is what I came up with:

In the first approach (not recommended) you can turn off config.reconfirmable, update attributes and turn it on again:

Devise.reconfirmable = false
user.update_attributes(params[:user])
Devise.reconfirmable = true

The second approach (it was recommended) is to use update_column method which saves attribute without callbacks. Please note that this method also turns off validations, so before you perform it, you have to check if the email (and other attributes) is correct. Update action for users_controller.rb with this approach can look like this:

def update
 @user = User.find(params[:id])
 if @user.update_attributes(params[:user])
  @user.update_column(:email, params[:user][:email])
  flash[:notice] = "User was successfully updated."
  redirect_to edit_admin_user_path(@user)
 else
  render :edit
 end
end

The third solution (added as comment by Stevo - thanks mate!) is now recommended:

def update
 @user = User.find(params[:id])
 @user.skip_reconfirmation!
 if @user.update_attributes(params[:user])
  flash[:notice] = "User was successfully updated."
  redirect_to edit_admin_user_path(@user)
 else
  render :edit
 end
end

3 Responses
Add your response

Nice :) The former solution look more clean for me - I see clearly that we disable some magic for some duration. The latter looks very confusing and looks wrong at the first look, before you reach the "AHA! DEVISE!" moment :)

over 1 year ago ·

Ok, I've red source a bit, and it seems, that you can achieve the exactly same effect by:

user.skip_reconfirmation!
over 1 year ago ·

Just what I was looking for. Nice job!

over 1 year ago ·