Validates_* model issue


#1

I have an AdminUser model that is giving me problems. I was using
validates_presence_of and validates_confirmation_of for my password
attribute and that worked fine for adding new admin users, but did not
when editing existing admin users. When editing an admin user record I
need the ability to have the password and password confirmation fields
on the form but ignore them if they are blank. I did not see a simple
way to do this using validates_* methods. I removed my
validates_presence_of and validates_confirmation_of calls for my
password attribute and instead added validate_on_create and
validate_on_update methods:

def validate_on_create
if self.password.length == 0
errors.add(:password, ‘must be present’)
end
unless passwords_same?
errors.add(:password, ‘confirmation must match password’)
end
end

def validate_on_update
if self.password.length > 0
unless passwords_same?
errors.add(:password, ‘confirmation must match password’)
end
end
end

The problem I’m having is with the validate_on_update method. When I
enter a single password without a valid password confirmation it works
as it should, errors occur. When I enter no password and no password
confirmation it works as it should, no errors occur. When I add a valid
password and password confirmation, no errors occur but the password is
not updated in the database.

I’ve tried debugging by adding breakpoints before and after the
@admin_user.save call. The @admin_user password and
password_confirmation attributes do not seem to be changing when I
supply the correct conditions for a password update.

Here is my model:

class AdminUser < ActiveRecord::Base

attr_accessor :password,
:password_confirmation

validates_presence_of :login

validates_uniqueness_of :login,
:on => :create,
:message => ‘is already in the system’

def before_create
self.hashed_password = AdminUser.hash_password(self.password)
end

def after_create
@password = nil
end

def validate_on_create
if self.password.length == 0
errors.add(:password, ‘must be present’)
end
unless passwords_same?
errors.add(:password, ‘confirmation must match password’)
end
end

def validate_on_update
if self.password.length > 0
unless passwords_same?
errors.add(:password, ‘confirmation must match password’)
end
end
end

def passwords_same?
self.password == self.password_confirmation
end

def try_to_login
AdminUser.login( self.login, self.password )
end

private

def self.hash_password(password)
Digest::SHA1.hexdigest(password)
end

def self.login(login, password)
hashed_password = hash_password(password || ‘’)
find(:first, :conditions => [‘login = ? AND hashed_password = ?’,
login, hashed_password])
end

end

Here is my controller:

class AdminUserController < ApplicationController

before_filter :authorize_admin

layout ‘admin’

def index
@admin_users = AdminUser.find(:all)
end

def edit
begin
@admin_user = AdminUser.find(params[:id])
rescue ActiveRecord::RecordNotFound
flash[:notice] = ‘Admin user not found’
redirect_to :controller => ‘admin_user’
end
if request.post?
breakpoint
if @admin_user.update_attributes(params[:admin_user])
breakpoint
flash[:notice] = ‘Admin user updated’
redirect_to :controller => ‘admin_user’
else
flash[:notice] = ‘Admin user not updated’
end
end
end

def add
if request.get?
@admin_user = AdminUser.new
else
@admin_user = AdminUser.new(params[:admin_user])
if @admin_user.save
flash[:notice] = ‘Admin user added’
redirect_to :controller => ‘admin_user’
else
flash[:notice] = ‘Admin user not added’
end
end
end

def delete
admin_user = AdminUser.find(params[:id])
admin_user.destroy
flash[:notice] = ‘Admin user deleted’
redirect_to :controller => ‘admin_user’
end

end

TIA,


Greg D.
Zend Certified Engineer
MySQL Core Certification
http://destiney.com/