# Model password validation

**URL:** <https://discuss.rubyonrails.org/t/model-password-validation/694>\
**Category:** rubyonrails-talk\
**Created:** [August 29, 2006, 10:26am UTC](https://discuss.rubyonrails.org/t/model-password-validation/694 "2006-08-29T10:26:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jordan\_Elver](https://avatars.discourse-cdn.com/v4/letter/j/b5ac83/32.png) [@Jordan\_Elver](https://discuss.rubyonrails.org/u/Jordan_Elver)\
**Post date:** [August 29, 2006, 10:26am UTC](https://discuss.rubyonrails.org/t/model-password-validation/694/1 "2006-08-29T10:26:24Z")

</div>

Hi, I'm doing something that seems so simple, but I can't figure it out. I'm writing a change password function for the "my account" section of a site. I want the user to enter their old password and their new password (and a confirmation), and then check that the old password matches before updating the record.

However, I don't know how to keep the old password around in order to do the validation. Because the validations happen in the model, the attributes are wiped out when assigning the new password value to the object.

I have to admit that I'm having trouble with validations generally. Database stuff is fine and relatively easy, but anything not backed by the database and I'm at a loss.

Does this make sense? How do you handle this?

Cheers, Jord

---

<div class="post-metadata">

**Author:** ![bphogan](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/bphogan/32/4186_2.png) [@bphogan](https://discuss.rubyonrails.org/u/bphogan)\
**Post date:** [August 29, 2006, 6:00pm UTC](https://discuss.rubyonrails.org/t/model-password-validation/694/2 "2006-08-29T18:00:07Z")

</div>

No no no.

I have to disagree. This ‘change password’ should be called in the model.

However, I’d refactor it a bit.

view:

Old password: \<% password\_field\_tag %\> New password: \<% password\_field(:user, :password) %\>

New password (confirm): \<% password\_field(:user, :password\_confirmation) %\>

controller

def change\_password

end

---

<div class="post-metadata">

**Author:** ![bphogan](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/bphogan/32/4186_2.png) [@bphogan](https://discuss.rubyonrails.org/u/bphogan)\
**Post date:** [August 29, 2006, 6:13pm UTC](https://discuss.rubyonrails.org/t/model-password-validation/694/3 "2006-08-29T18:13:15Z")

</div>

Sorry… gmail’s being a pest. I tried to post an example but it got cut off. The solution provided by Lucasz is a great one. However, I still like to have that sort of stuff in the model instead of the controller because I may have various ways for a password to be changed.

---

<div class="post-metadata">

**Author:** ![Jordan\_Elver](https://avatars.discourse-cdn.com/v4/letter/j/b5ac83/32.png) [@Jordan\_Elver](https://discuss.rubyonrails.org/u/Jordan_Elver)\
**Post date:** [September 6, 2006, 6:50pm UTC](https://discuss.rubyonrails.org/t/model-password-validation/694/4 "2006-09-06T18:50:21Z")

</div>

Thanks both for your suggestions. I've managed to come up with something that works now.

I've added a virtual attribute to take the current password from the user and this is only validated when a password is changed. So, now I have something like this:

Model:

class Customer \< ActiveRecord::Base &nbsp;&nbsp;&nbsp;&nbsp;attr\_accessor :current\_password &nbsp;&nbsp;&nbsp;&nbsp;validates\_presence\_of :current\_password, :on =\> :update, :if =\> :password\_change?

&nbsp;&nbsp;&nbsp;&nbsp;def change\_password(attributes) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@password\_change = true &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.attributes = attributes &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;save &nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;private

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def validate\_on\_update &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if password\_change? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errors.add(:current\_password, "is incorrect") unless encrypt(current\_password) == crypted\_password &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def password\_change? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@password\_change &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end end

Controller:

class AccountController \< ApplicationController &nbsp;&nbsp;&nbsp;&nbsp;def change\_password &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@customer = @current\_customer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if request.post? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @customer.change\_password(params[:customer]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "Your password has been changed" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;end end

Thanks for your advice.

Cheers, Jord

---

<div class="post-metadata">

**Author:** ![bphogan](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/bphogan/32/4186_2.png) [@bphogan](https://discuss.rubyonrails.org/u/bphogan)\
**Post date:** [September 6, 2006, 8:31pm UTC](https://discuss.rubyonrails.org/t/model-password-validation/694/5 "2006-09-06T20:31:34Z")

</div>

Very nice.
