diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2004-11-24 01:04:44 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2004-11-24 01:04:44 +0000 |
commit | db045dbbf60b53dbe013ef25554fd013baf88134 (patch) | |
tree | 257830e3c76458c8ff3d1329de83f32b23926028 /activerecord/examples | |
download | rails-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.png | bin | 0 -> 40623 bytes | |||
-rw-r--r-- | activerecord/examples/associations.rb | 87 | ||||
-rw-r--r-- | activerecord/examples/shared_setup.rb | 15 | ||||
-rw-r--r-- | activerecord/examples/validation.rb | 88 |
4 files changed, 190 insertions, 0 deletions
diff --git a/activerecord/examples/associations.png b/activerecord/examples/associations.png Binary files differnew file mode 100644 index 0000000000..661c7a8bbc --- /dev/null +++ b/activerecord/examples/associations.png 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 |