Model password validation

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

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

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.

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
    attr_accessor :current_password
    validates_presence_of :current_password, :on => :update, :if =>
:password_change?

    def change_password(attributes)
      @password_change = true
      self.attributes = attributes
      save
    end

    private

        def validate_on_update
            if password_change?
                errors.add(:current_password, "is incorrect") unless
encrypt(current_password) == crypted_password
            end
        end

        def password_change?
            @password_change
        end
end

Controller:

class AccountController < ApplicationController
    def change_password
        @customer = @current_customer
        if request.post?
            if @customer.change_password(params[:customer])
                flash[:notice] = "Your password has been changed"
            end
        end
    end
end

Thanks for your advice.

Cheers,
Jord

Very nice.