0
votes

I'm new to rails and devise, so I'm trying to understand what is going on. I am following the devise wiki for allowing users to edit their own password, found here: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password.

What I find confusing is that even though I am using :validatable in my model, it seems that I am able to submit the form even if I leave password/password_confirmation blank, as long as I complete current_password. It seems this has something to do with the fact that in validatable.rb, that there is a validation for password only if !password.nil? per line 54.

So I decided to look at debug(params) on form submission, and it seems indeed that if I leave the password/password_confirmation fields blank, then password/password_confirmation do not appear in the params hash at all (and though password.nil? is true?).

What I don't understand is why this happens? Even if I leave the password field blank, shouldn't password appear in params just like any other field, as "password" => ""? Since I'm using my own controller action to process the form, how is it that password is not in params?

1
How are you determining that the password and confirmation fields are not passed in the params? Are you logging it? I actually just threw together a barebones Rails app with Devise just to see if this happens, and for me it did not. They're empty strings in the params, as you'd expect.numbers1311407
In the controller action found from devise's wiki page here ( github.com/plataformatec/devise/wiki/…), I added this to the beginning of the update_password action: flash[:notice] = params[:user] When I leave the password/password_confirmation fields blank on the form, the flash notice simply states "{}". However, I do see in the server console that "password" => "[FILTERED]".robotron2000
@numbers1311407 Based on what you wrote, I decided to try adding if statement to test if params[:user][:password].nil? on submission of a blank password field. You are right, the field is NOT nil, only blank. Guess now I'm confused as to why flash[:notice] = params[:user] returns {} only? Since password is blank, I would've thought that the devise's validatable shown here would've caught the validation error on blank password submission.robotron2000

1 Answers

1
votes

The update_with_password method that is used on that wiki page is what's causing your confusion. It deletes both password and password_confirmation from the params if they are blank, as seen here.

This seems like an oversight on the wiki page, as it's describing how to implement your own change password action. This is definitely an issue in that case (submitting a "change password" form without filling out a password should probably fail).

Anyway, you could work around it, and still use the update_with_password method, just by checking to see if the password is blank beforehand, something like this (refactored as you like):

def update_password
  @user = User.find(current_user.id)

  if params[:user][:password].blank?
    @user.errors.add(:password, :blank)
    render "edit"
  elsif @user.update_attributes(params[:user])
    # Sign in the user by passing validation in case his password changed
    sign_in @user, :bypass => true
    redirect_to root_path
  else
    render "edit"
  end
end