aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/examples
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
commitdb045dbbf60b53dbe013ef25554fd013baf88134 (patch)
tree257830e3c76458c8ff3d1329de83f32b23926028 /activerecord/examples
downloadrails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.gz
rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.bz2
rails-db045dbbf60b53dbe013ef25554fd013baf88134.zip
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/examples')
-rw-r--r--activerecord/examples/associations.pngbin0 -> 40623 bytes
-rw-r--r--activerecord/examples/associations.rb87
-rw-r--r--activerecord/examples/shared_setup.rb15
-rw-r--r--activerecord/examples/validation.rb88
4 files changed, 190 insertions, 0 deletions
diff --git a/activerecord/examples/associations.png b/activerecord/examples/associations.png
new file mode 100644
index 0000000000..661c7a8bbc
--- /dev/null
+++ b/activerecord/examples/associations.png
Binary files differ
diff --git a/activerecord/examples/associations.rb b/activerecord/examples/associations.rb
new file mode 100644
index 0000000000..b0df367321
--- /dev/null
+++ b/activerecord/examples/associations.rb
@@ -0,0 +1,87 @@
+require File.dirname(__FILE__) + '/shared_setup'
+
+logger = Logger.new(STDOUT)
+
+# Database setup ---------------
+
+logger.info "\nCreate tables"
+
+[ "DROP TABLE companies", "DROP TABLE people", "DROP TABLE people_companies",
+ "CREATE TABLE companies (id int(11) auto_increment, client_of int(11), name varchar(255), type varchar(100), PRIMARY KEY (id))",
+ "CREATE TABLE people (id int(11) auto_increment, name varchar(100), PRIMARY KEY (id))",
+ "CREATE TABLE people_companies (person_id int(11), company_id int(11), PRIMARY KEY (person_id, company_id))",
+].each { |statement|
+ # Tables doesn't necessarily already exist
+ begin; ActiveRecord::Base.connection.execute(statement); rescue ActiveRecord::StatementInvalid; end
+}
+
+
+# Class setup ---------------
+
+class Company < ActiveRecord::Base
+ has_and_belongs_to_many :people, :class_name => "Person", :join_table => "people_companies", :table_name => "people"
+end
+
+class Firm < Company
+ has_many :clients, :foreign_key => "client_of"
+
+ def people_with_all_clients
+ clients.inject([]) { |people, client| people + client.people }
+ end
+end
+
+class Client < Company
+ belongs_to :firm, :foreign_key => "client_of"
+end
+
+class Person < ActiveRecord::Base
+ has_and_belongs_to_many :companies, :join_table => "people_companies"
+ def self.table_name() "people" end
+end
+
+
+# Usage ---------------
+
+logger.info "\nCreate fixtures"
+
+Firm.new("name" => "Next Angle").save
+Client.new("name" => "37signals", "client_of" => 1).save
+Person.new("name" => "David").save
+
+
+logger.info "\nUsing Finders"
+
+next_angle = Company.find(1)
+next_angle = Firm.find(1)
+next_angle = Company.find_first "name = 'Next Angle'"
+next_angle = Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first
+
+Firm === next_angle
+
+
+logger.info "\nUsing has_many association"
+
+next_angle.has_clients?
+next_angle.clients_count
+all_clients = next_angle.clients
+
+thirty_seven_signals = next_angle.find_in_clients(2)
+
+
+logger.info "\nUsing belongs_to association"
+
+thirty_seven_signals.has_firm?
+thirty_seven_signals.firm?(next_angle)
+
+
+logger.info "\nUsing has_and_belongs_to_many association"
+
+david = Person.find(1)
+david.add_companies(thirty_seven_signals, next_angle)
+david.companies.include?(next_angle)
+david.companies_count == 2
+
+david.remove_companies(next_angle)
+david.companies_count == 1
+
+thirty_seven_signals.people.include?(david) \ No newline at end of file
diff --git a/activerecord/examples/shared_setup.rb b/activerecord/examples/shared_setup.rb
new file mode 100644
index 0000000000..6ede4b1d35
--- /dev/null
+++ b/activerecord/examples/shared_setup.rb
@@ -0,0 +1,15 @@
+# Be sure to change the mysql_connection details and create a database for the example
+
+$: << File.dirname(__FILE__) + '/../lib'
+
+require 'active_record'
+require 'logger'; class Logger; def format_message(severity, timestamp, msg, progname) "#{msg}\n" end; end
+
+ActiveRecord::Base.logger = Logger.new(STDOUT)
+ActiveRecord::Base.establish_connection(
+ :adapter => "mysql",
+ :host => "localhost",
+ :username => "root",
+ :password => "",
+ :database => "activerecord_examples"
+)
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