aboutsummaryrefslogblamecommitdiffstats
path: root/activerecord/examples/validation.rb
blob: e6a448afb8a65a700fcda57d23d1a8a6db5c2b17 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                                                                                


































































                                                                                                                 
require File.dirname(__FILE__) + '/shared_setup'

logger = Logger.new(STDOUT)

# Database setup ---------------

logger.info "\nCreate tables"

[ "DROP TABLE people",
  "CREATE TABLE people (id int(11) auto_increment, name varchar(100), pass varchar(100), email varchar(100), PRIMARY KEY (id))"
].each { |statement|
  begin; ActiveRecord::Base.connection.execute(statement); rescue ActiveRecord::StatementInvalid; end # Tables doesn't necessarily already exist
}


# Class setup ---------------

class Person < ActiveRecord::Base
  # Using 
  def self.authenticate(name, pass)
    # find_first "name = '#{name}' AND pass = '#{pass}'" would be open to sql-injection (in a web-app scenario)
    find_first [ "name = '%s' AND pass = '%s'", name, pass ]
  end

  def self.name_exists?(name, id = nil)
    if id.nil?
      condition = [ "name = '%s'", name ]
    else
      # Check if anyone else than the person identified by person_id has that user_name
      condition = [ "name = '%s' AND id <> %d", name, id ]
    end

    !find_first(condition).nil?
  end

  def email_address_with_name
    "\"#{name}\" <#{email}>"
  end
        
  protected
    def validate
      errors.add_on_empty(%w(name pass email))
      errors.add("email", "must be valid") unless email_address_valid?
    end

    def validate_on_create
      if attribute_present?("name") && Person.name_exists?(name)
          errors.add("name", "is already taken by another person")
      end
    end

    def validate_on_update
      if attribute_present?("name") && Person.name_exists?(name, id)
          errors.add("name", "is already taken by another person")
      end
    end
  
  private
    def email_address_valid?() email =~ /\w[-.\w]*\@[-\w]+[-.\w]*\.\w+/ end
end

# Usage ---------------

logger.info "\nCreate fixtures"
david = Person.new("name" => "David Heinemeier Hansson", "pass" => "", "email" => "")
unless david.save
  puts "There was #{david.errors.count} error(s)"
  david.errors.each_full { |error| puts error }
end

david.pass = "something"
david.email = "invalid_address"
unless david.save
  puts "There was #{david.errors.count} error(s)"
  puts "It was email with: " + david.errors.on("email")
end

david.email = "david@loudthinking.com"
if david.save then puts "David finally made it!" end


another_david = Person.new("name" => "David Heinemeier Hansson", "pass" => "xc", "email" => "david@loudthinking")
unless another_david.save
  puts "Error on name: " + another_david.errors.on("name")
end