aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/examples/validation.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/examples/validation.rb')
-rw-r--r--activerecord/examples/validation.rb88
1 files changed, 88 insertions, 0 deletions
diff --git a/activerecord/examples/validation.rb b/activerecord/examples/validation.rb
new file mode 100644
index 0000000000..334a1685f7
--- /dev/null
+++ b/activerecord/examples/validation.rb
@@ -0,0 +1,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 \ No newline at end of file