Forum: Ruby on Rails validates_* model issue

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cd8e382b8a2d7885a26578209c4b4ada?d=identicon&s=25 destiney (Guest)
on 2005-11-28 02:05
(Received via mailing list)
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 Donald
Zend Certified Engineer
MySQL Core Certification
http://destiney.com/
This topic is locked and can not be replied to.