aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/examples/validation.rb
blob: 334a1685f78df227eaae7c528282d4fecc9519f1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
  # Active Record can only guess simple table names like Card/cards, Company/companies
  def self.table_name() "people" end

  # 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