views:

51

answers:

4

My User model contains :name, :email, and :password fields. All 3 have validations for length. An "update account" web page allows the user to update his name and email address, but not password. When submitted, params[:user] is

{"name"=>"Joe User", "email"=>"[email protected]"}

Note there is no "password" key because the form doesn't contain such an input field.

When I call

@user.update_attributes(params[:user])

the password validation fails. However, since I'm not attempting to update the password, I don't want the password validation to run on this update. I'm confused why the password validation is running when params[:user] doesn't contain a "password" key.

Note that I want to have a separate web page elsewhere that allows the user to update his password. And for that submission, the password validation should run.

Thank you.

A: 

An app that I am working on uses the following:

    validates_confirmation_of :password, 
                              :if => Proc.new { |account| 
                                                !account.password.blank? 
                                                || !account.password_confirmation.blank? 
                                                || account.new_record? }

Depending on your requirements, you might want to remove the new_record? check

Jeff Paquette
That seems like its removing the point of confirmation - You won't confirm if they didn't specify the confirmation in the form.
mathepic
Hmm... looks like a bug, you're right.
Jeff Paquette
A: 

In your user model, you could just ignore the password validation if it's not set.

validates_length_of :password, :minimum => N, :unless => lambda {|u| u.password.nil? }
Beerlington
+2  A: 

My application does something like this

attr_accessor :updating_password

validates_confirmation_of :password, :if => should_validate_password?

def should_validate_password?
  updating_password || new_record?
end

so you have to model.updating_password = true for the verification to take place, and you don't have to do this on creation.

Which I found at a good railscast at http://railscasts.com/episodes/41-conditional-validations

mathepic
Thank you, mathepic. This worked for me.
Sanjay
A: 

Using update_attributes will not change the value of the password if there is no key for it in the params hash.

Validation doesn't run against the changed fields only. It validates existing values too.

Your validation must be failing because the password field contains some invalid content that's already saved in the database. I'm guessing it's probably because you're hashing it after validation and you're trying to validate the hashed string.

You can use a virtual attribute (an instance variable or method) that you validate with a custom method, and then assign the hash to the stored password field. Have a look at this technique for ideas.

Andrew Vit