# How to skip password validation when updating other fields?

**URL:** <https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271>\
**Category:** Rails\
**Created:** [March 29, 2006, 11:20pm UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271 "2006-03-29T23:20:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 29, 2006, 11:20pm UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/1 "2006-03-29T23:20:09Z")

</div>

Besides the hashed password, which is saved to db, I have two  
password-attributes in my User model:

attr\_accessor :password, :password\_confirmation

I have validations on these attributes, and I need them to work both on  
create and update, since I have pages for changing and resetting the  
password.

Now when I want to update just the user’s login name, I guess I have the  
next options:

1. 

user = User.find(session[:user\_id])  
user.login = params[:login]  
user.save  
=\> Won’t work because the password and password\_confirmation validations  
hit.

1. 

user = User.find(session[:user\_id])  
user.login = params[:login]  
user.update\_attributes(:login =\> params[:login] )  
=\> Won’t work because the password and password\_confirmation validations  
hit.

1. 

user = User.find(session[:user\_id])  
user.login = params[:login]  
user.update\_attribute(:login, params[:login] )  
=\> Updates the fiels to db, but passes all validations. Now I think it’s  
bad idea to do the validations every time in the controller when I need  
to update a field.

1. 

user = User.find(session[:user\_id])  
user.login = params[:login]  
if user.valid?  
user.update\_attribute(:login, params[:login] )  
end  
=\> Won’t work because the password and password\_confirmation validations  
hit.

Is there any way to skip the validations for the password attributes?

I’ve been thinkin of creating validation method in the user model, that  
skips the password-fields like this:

def validate\_all\_but\_password  
loop through validations  
if the validation name doesn’t equal ‘password’ or  
‘password\_confirmation’  
run the validation

and then call it before update\_attribute.

What do you think, would this be a good practise, or is there another  
way to solve this problem?

---

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 30, 2006, 12:19am UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/2 "2006-03-30T00:19:40Z")

</div>

If I just had surfed to the api doc before posting… heh

Found the solution, added this on the validations of password:

:if =\> :validate\_password

then before I call user.save I call user.dont\_validate\_password, which  
sets instance variable to false and the validate\_password method then  
returns false.

---

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 30, 2006, 12:21am UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/3 "2006-03-30T00:21:50Z")

</div>

How about specifying that the validation only be performed upon model  
creation?

E.g. validates\_confirmation\_of :password, :password\_confirmation, :on =\>  
:create

---

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 30, 2006, 12:38am UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/4 "2006-03-30T00:38:31Z")

</div>

Don Walker wrote:

> How about specifying that the validation only be performed upon model  
> creation?
> 
> E.g. validates\_confirmation\_of :password, :password\_confirmation, :on =\>  
> :create

But I need to validate the input also when the user updates the  
password.

---

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 30, 2006, 1:01am UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/5 "2006-03-30T01:01:10Z")

</div>

Basically, you just have to look at the before\_create and before\_save  
methods.

Here’s what I do… Password field is validated on create only.  
Password is set on update only if the password field is not nil.

class User \< ActiveRecord::Base  
attr\_accessor :password  
attr\_accessible :username, :password, :email  
validates\_uniqueness\_of :username, :email  
validates\_presence\_of :username, :email  
has\_and\_belongs\_to\_many :machines

# 

def validate\_on\_create  
errors.add\_to\_base(“Password field must not be left blank!”) if  
self.password == “” or self.password.nil?  
end

# hash the password for storage in the DB

def before\_create  
self.hashed\_password = User.hash\_password(self.password)  
end

# hash the password before updating but only if the password field is

actually filled in.  
def before\_update()  
unless self.password.nil?  
self.password = User.hash\_password(self.password)  
end  
end

def after\_create  
self.password = nil  
end

end

---

<div class="post-metadata">

**Author:** ![JJJJJJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/53a042/32.png) [@JJJJJJ](https://www.ruby-forum.com/u/JJJJJJ)\
**Post date:** [March 30, 2006, 1:01am UTC](https://www.ruby-forum.com/t/how-to-skip-password-validation-when-updating-other-fields/56271/6 "2006-03-30T01:01:10Z")

</div>

You could do it this way in your model…

```
validates_presence_of :password, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?

```

where…

protected  
def password\_required?  
hashed\_password.blank? or not password.blank?  
end
