Introduction to Active Record - Silicon Valley Ruby Conference 2007
-
Upload
rabble- -
Category
Economy & Finance
-
view
46.443 -
download
5
Transcript of Introduction to Active Record - Silicon Valley Ruby Conference 2007
![Page 1: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/1.jpg)
Introduction to Active Record
Evan ‘Rabble’ Henshaw-Plath [email protected] - Yahoo! Brickhouse
anarchogeek.com - testingrails.com
![Page 2: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/2.jpg)
Active Record is a Design Pattern
An object that wraps a row in a database table or view, encapsulates the database access, and
adds domain logic on that data.
![Page 3: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/3.jpg)
Active Recordthe Pattern
Active Record uses the most obvious approach,putting data access logic in the domain object.
- Martin Fowler
Person last_name first_name dependents_count
insert update
get_exemption is_flagged_for_audit? get_taxable_earnings?
![Page 4: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/4.jpg)
One Class Per Table
CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `login` varchar(255), `email` varchar(255), `crypted_password` varchar(40), `salt` varchar(40), `created_at` datetime default NULL, `updated_at` datetime default NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
class User < ActiveRecord::Base end
The DatabaseThe Model Code
![Page 5: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/5.jpg)
One Object Per Row
![Page 6: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/6.jpg)
There Are Other Ways To Do it
• Table Data Gateway
• Row Data Gateway
• Data Mapper
• The Anti-Patterns
Active Record is just one ‘Data Source Architectural Pattern’
![Page 7: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/7.jpg)
Standard Active Record
• Direct mapping to the DB
• Class to table
• Object to row
• Simple, no relationship between objects
• Just a finder method with getters and setters
![Page 8: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/8.jpg)
ActiveRecordthe ruby library
Active Record is a library builtfor Ruby on Rails.
Makes CRUD EasyCreateReadUpdateDelete
![Page 9: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/9.jpg)
ActiveRecordthe ruby library
I have never seen an Active Record implementation as complete
or as useful as rails. - Martin Fowler
![Page 10: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/10.jpg)
Rails’ ActiveRecord
• DRY Conventions & Assumptions
• Validations
• Before and after filters
• Database Agnostic (mostly)
• Migrations
• Model relationships
• has_many, belongs_to, etc...
![Page 11: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/11.jpg)
What ActiveRecord Likes• mapping class names to
table names
• pluralized table names
• integer primary keys
• classname_id foreign keys
• simple schemas
• single table inheritance
![Page 12: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/12.jpg)
Active RecordDoesn’t Like • views
• stored methods
• foreign key constraints
• cascading commits
• split or clustered db’s
• enums
![Page 13: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/13.jpg)
The Basics
class User < ActiveRecord::Base end
./app/models/user.rb Loading a user
>> user_obj = User.find(2)=> #<User:0x352e8bc @attributes= {"salt"=>"d9ef...", "updated_at"=>"2007-04-19 10:49:15", "crypted_password"=>"9c1...", "id"=>"2", "remember_token"=>"a8d...", "login"=>"rabble", "created_at"=>"2007-04-19 10:49:15", "email"=>"[email protected]"}>
User Load (0.003175) SELECT * FROM users WHERE (users.id = 2) LIMIT 1
The SQL Log
![Page 14: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/14.jpg)
The Find Method
Find is the primary method of Active Record
Examples: User.find(23) User.find(:first) User.find(:all, :offset => 10, :limit => 10) User.find(:all, :include => [:account, :friends]) User.find(:all, :conditions => [“category in (?), categories, :limit => 50) User.find(:first).articles
![Page 15: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/15.jpg)
The Four Ways of Find
Find by id: This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
Find first: This will return the first record matched by the options used.
Find all: This will return all the records matched by the options used.
Indirectly: The find method is used for AR lookups via associations.
![Page 16: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/16.jpg)
Understanding Find
Model#find(:all, { parameters hash }
What Find Does: * generates sql * executes sql * returns an enumerable (array like object) * creates an AR model object for each row
![Page 17: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/17.jpg)
Find with :conditions
:conditions - An SQL fragment like "administrator = 1" or [ "user_name = ?", username ].
Student.find(:all, :conditions => [‘first_name = ? and status = ?’ ‘rabble’, 1])
New Style (Edge Rails Only)Student.find(:all, :conditions => {:first_name => “rabble”, :status => 1})
SQL Executed:SELECT * FROM students WHERE (first_name = 'rabble' and status = 1);
![Page 18: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/18.jpg)
Doing it Securely class User < ActiveRecord::Base def self.authenticate_unsafely(user_name, password) find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'") end
def self.authenticate_safely(user_name, password) find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ]) end
# Edge Rails Only (Next Version of Rails) def self.authenticate_safely_simply(user_name, password) find(:first, :conditions => { :user_name => user_name, :password => password }) end end
![Page 19: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/19.jpg)
Order By
:order - An SQL fragment like "created_at DESC, name".
Student.find(:all, :order => ‘updated_at DESC’)
SQL Executed:SELECT * FROM users ORDER BY created_at;
![Page 20: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/20.jpg)
Group By
:group - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
Student.find(:all, :group => ‘graduating_class’)
SQL Executed:SELECT * FROM users GROUP BY graduating_class;
![Page 21: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/21.jpg)
Limit & Offset:limit - An integer determining the limit on the number of rows that should be returned.
:offset- An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows.
Student.find(:all, :limit => 10, :offset => 0)
SQL Executed:SELECT * FROM users LIMIT 0, 10;
![Page 22: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/22.jpg)
Joins
:joins - An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". (Rarely needed).
Student.find(:all, :join => "LEFT JOIN comments ON comments.post_id = id")
SQL Executed:SELECT * FROM users GROUP BY graduating_class;
Returns read only objects unless you say :readonly => false
![Page 23: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/23.jpg)
Alternative Finds
find_by_sql
find_by_attribute_and_attribute2
find_or_create
Depreciated Find’sfind_firstfind_allfind_on_conditions
![Page 24: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/24.jpg)
class Project < ActiveRecord::Base belongs_to :portfolio has_one :project_manager has_many :milestones has_and_belongs_to_many :categoriesend
The Four Primary Associations
belongs_tohas_onehas_manyhas_and_belongs_to_many
Associations
![Page 25: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/25.jpg)
One to One has_one & belongs_to
Many to One has_many & belongs_to
Many to Many has_and_belongs_to_many has_many :through
Associations
![Page 26: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/26.jpg)
One to One
Use has_one in the base, and belongs_to in the associated model.
class Employee < ActiveRecord::Base has_one :office end
class Office < ActiveRecord::Base belongs_to :employee # foreign key - employee_id end
![Page 27: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/27.jpg)
One To One Example>> joe_employee = Employee.find_by_first_name('joe')SELECT * FROM employees WHERE (employees.`first_name` = 'joe') LIMIT 1=> #<Employee:0x36beb14 @attributes={"id"=>"1", "first_name"=>"joe", "last_name"=>"schmo", "created_at"=>"2007-04-21 09:08:59"}>
>> joes_office = joe_employee.officeSELECT * FROM offices WHERE (offices.employee_id = 1) LIMIT 1=> #<Office:0x36bc06c @attributes={"employee_id"=>"1", "id"=>"1", "created_at"=>"2007-04-21 09:11:44", "location"=>"A4302"}>
>> joes_office.employeeSELECT * FROM employees WHERE (employees.`id` = 1)=> #<Employee:0x36b6ef0 @attributes={"id"=>"1", "first_name"=>"joe", "last_name"=>"schmo", "created_at"=>"2007-04-21 09:08:59"}>
![Page 28: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/28.jpg)
belongs_toOne to One Relationship. Use belong to when the foreign key is in THIS table.
• Post#author (similar to Author.find(author_id) )
• Post#author=(author) (similar to post.author_id = author.id)
• Post#author? (similar to post.author == some_author)
• Post#author.nil?
• Post#build_author (similar to post.author = Author.new)
• Post#create_author (similar to post.author = Author; post.author.save;
![Page 29: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/29.jpg)
Defining belongs_toclass Employee < ActiveRecord::Base belongs_to :firm, :foreign_key => "client_of"
belongs_to :author, :class_name => "Person", :foreign_key => "author_id"
belongs_to :valid_coupon, :class_name => "Coupon",
:foreign_key => "coupon_id", :conditions => 'discounts > #{payments_count}'
belongs_to :attachable, :polymorphic => trueend
![Page 30: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/30.jpg)
has_one
• Account#beneficiary (similar to Beneficiary.find(:first, :conditions => "account_id = #{id}"))
• Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save)
• Account#beneficiary.nil?
• Account#build_beneficiary (similar to Beneficiary.new("account_id" => id))
• Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b)
One to One Relationship. Use has_one when the foreign key is in the OTHER table.
![Page 31: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/31.jpg)
Defining has_oneclass Employee < ActiveRecord::Base
# destroys the associated credit card has_one :credit_card, :dependent => :destroy # updates the associated records foreign key value to null rather than destroying it has_one :credit_card, :dependent => :nullify has_one :last_comment, :class_name => "Comment", :order => "posted_on" has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'"
has_one :attachment, :as => :attachable
end
![Page 32: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/32.jpg)
One to ManyOne-to-manyUse has_many in the base, and belongs_to in the associated model.
class Manager < ActiveRecord::Base has_many :employeesend
class Employee < ActiveRecord::Base belongs_to :manager # foreign key - manager_idend
![Page 33: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/33.jpg)
>> benevolent_dictator = Manager.find(:first, :conditions => ['name = "DHH"']) SELECT * FROM managers WHERE (name = "DHH") LIMIT 1=> #<Manager:0x369b7b8 @attributes={"name"=>"DHH", "id"=>"1", "created_at"=>"2007-04-21 09:59:24"}>
>> minions = benevolent_dictator.employees SELECT * FROM employees WHERE (employees.manager_id = 1)=> [#<Employee:0x36926a4 @attributes={"manager_id"=>"1", "id"=>"1", "first_name"=>"joe", "last_name"=>"schmo", "created_at"=>"2007-04-21 09:08:59"}>, #<Employee:0x36925f0 @attributes={"manager_id"=>"1", "id"=>"2", "first_name"=>"funky", "last_name"=>"monkey", "created_at"=>"2007-04-21 09:58:20"}>]
One to Many
![Page 34: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/34.jpg)
has_many
• Firm#clients (similar to Clients.find :all, :conditions => "firm_id = #{id}")
• Firm#clients<<
• Firm#clients.delete
• Firm#client_ids
• Firm#client_ids=
• Firm#clients=
Augmenting the Model
![Page 35: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/35.jpg)
has_many
• Firm#client.clear
• Firm#clients.empty? (similar to firm.clients.size == 0)
• Firm#clients.size (similar to Client.count "firm_id = #{id}")
• Firm#clients.find (similar to Client.find(id, :conditions => "firm_id = #{id}"))
• Firm#clients.build (similar to Client.new("firm_id" => id))
• Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c)
![Page 36: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/36.jpg)
has_many examples
class Employee < ActiveRecord::Base has_many :comments, :order => "posted_on" has_many :comments, :include => :author has_many :people, :class_name => "Person", :conditions => "deleted = 0", :order => "name" has_many :tracks, :order => "position", :dependent => :destroy has_many :comments, :dependent => :nullify has_many :tags, :as => :taggable has_many :subscribers, :through => :subscriptions, :source => :user has_many :subscribers, :class_name => "Person", :finder_sql => 'SELECT DISTINCT people.* ' + 'FROM people p, post_subscriptions ps ' + 'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' + 'ORDER BY p.first_name'end
![Page 37: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/37.jpg)
Many to Many
Simple Joiner Tablehas_and_belongs_to_many
Joiner Modelhas_many :through
![Page 38: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/38.jpg)
has_and_belongs_to_many
The Simple Joiner Table Way
![Page 39: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/39.jpg)
neglected by
rails-core
has_and_belongs_to_many
![Page 40: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/40.jpg)
has_and_belongs_to_many
• Developer#projects
• Developer#projects<<
• Developer#projects.delete
• Developer#projects=
• Developer#projects_ids
• Developer#projects_ids=
• Developer#clear
Augmenting the Model
![Page 41: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/41.jpg)
has_and_belongs_to_many
• Developer#projects.empty?
• Developer#projects.size
• Developer#projects.find(id) # Also find(:first / :all)
• Developer#projects.build #(similar to Project.new("project_id" => id))
• Developer#projects.create (similar to c = Project.new("project_id" => id); c.save; c)
![Page 42: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/42.jpg)
habtm example create_table :developers do |t| t.column :name, :string t.column :created_at, :datetime end
create_table :projects do |t| t.column :name, :string t.column :created_at, :datetime end
create_table(:developers_projects, :id => false) do |t| t.column :developer_id, :integer t.column :project_id, :integer end
![Page 43: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/43.jpg)
habtm example>> d = Developer.find(1) SELECT * FROM developers WHERE (developers.`id` = 1)=> #<Developer:0x32bc7dc @attributes={"name"=>"rabble", "id"=>"1", "created_at"=>nil}>
>> d.projects SELECT * FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE (developers_projects.developer_id = 1 )=> [#<Project:0x3257cc4 @attributes= {"name"=>"ragi", "project_id"=>"1", "id"=>"1", "developer_id"=>"1", "created_at"=>nil}>, #<Project:0x3257c10 @attributes= {"name"=>"acts_as_autenticated", "project_id"=>"3", "id"=>"3", "developer_id"=>"1", "created_at"=>nil}>]
![Page 44: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/44.jpg)
has_many :through
DHH’s One True Way
of Many to Many
![Page 45: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/45.jpg)
has_many :through
Full Joiner Model
![Page 46: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/46.jpg)
has_many :through
class Appearance < ActiveRecord::Base belongs_to :dancer belongs_to :movieend
class Dancer < ActiveRecord::Base has_many :appearances, :dependent => true has_many :movies, :through => :appearancesend
class Movie < ActiveRecord::Base has_many :appearances, :dependent => true has_many :dancers, :through => :appearancesend
![Page 47: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/47.jpg)
Validations
class User < ActiveRecord::Base validates_confirmation_of :login, :password validates_confirmation_of :email, :message => "should match confirmation" validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :createend
![Page 48: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/48.jpg)
Validations
• Keeping Data Clean
• In object validation of fields, calculated validations
• Instead of key constraints
• The database is for storage, the model is for the business logic
• Kinds of validations, custom validations, etc...
![Page 49: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/49.jpg)
But Wait?
• Aren’t format, presence, relationship validations supposed to be the database’s job?
• Traditionally, yes.
• ActiveRecord does constraints in the model, not the database
![Page 50: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/50.jpg)
But Why?
• Validations & Constraints are Business Logic
• Business logic should be in the model
• It makes things easy
• End users can get useful error messages
• Makes the postback pattern work well
![Page 51: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/51.jpg)
Data Integrity?
• It’s still possible to do constraints in the db
• But it’s not as necessary
• Validations are constraints which make sense in terms of functionality of the app
• The rails ways is to just use validations
• Most DBA’s insist on foreign_key constraints
![Page 52: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/52.jpg)
What AR Returns?
• Enumerable Objects (kind of like arrays)
• Preselects and instantiates objects
• Nifty methods: to_yaml, to_xml, to_json
![Page 53: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/53.jpg)
Output Formats#<Employee:0x36926a4 @attributes= {"manager_id"=>"1", "id"=>"1", "first_name"=>"joe", "last_name"=>"schmo", "created_at"=>"2007-04-21 09:08:59"}>
ruby - inspect--- !ruby/object:Employee attributes: manager_id: "1" id: "1" first_name: joe last_name: schmo created_at: 2007-04-21 09:08:59
to_yaml
{attributes: {manager_id: "1", id: "1", first_name: "joe", last_name: "schmo", created_at: "2007-04-21 09:08:59"}}
to_json<?xml version="1.0" encoding="UTF-8"?><employee> <created-at type="datetime">2007-04-21T09:08:59-07:00</created-at> <first-name>joe</first-name> <id type="integer">1</id> <last-name>schmo</last-name> <manager-id type="integer">1</manager-id></employee>
to_xml
![Page 54: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/54.jpg)
Before & After Callbacks
* (-) save * (-) valid? * (1) before_validation * (2) before_validation_on_create * (-) validate * (-) validate_on_create * (3) after_validation * (4) after_validation_on_create * (5) before_save * (6) before_create * (-) create * (7) after_create * (8) after_save
class Subscription < ActiveRecord::Base before_create :record_signup
private def record_signup self.signed_up_on = Date.today end end
class Firm < ActiveRecord::Base # Destroys the associated clients and #people when the firm is destroyed before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } before_destroy { |record| Client.destroy_all "client_of = #{record.id}" } end
![Page 55: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/55.jpg)
Security
![Page 56: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/56.jpg)
Special Fields * created_at * created_on * updated_at * updated_on * lock_version * type * id
* #{table_name}_count * position * parent_id * lft * rgt * quote * template
![Page 57: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/57.jpg)
Active Record Tricks
![Page 58: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/58.jpg)
Drink the Kool aid?
![Page 59: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/59.jpg)
Flickr Photos Used:http://flickr.com/photos/brraveheart/114402291/http://flickr.com/photos/bright/253175260/http://flickr.com/photos/good_day/63617697/http://flickr.com/photos/rickharris/416150393/http://flickr.com/photos/babasteve/3322247/http://flickr.com/photos/olivander/28058685/http://flickr.com/photos/brraveheart/44052308/http://flickr.com/photos/ednothing/142393509/http://flickr.com/photos/alltheaces/87505524/http://flickr.com/photos/alfr3do/7436142/http://flickr.com/photos/gdominici/57975123/http://flickr.com/photos/josefstuefer/72512671/http://flickr.com/photos/uqbar/105440294/http://flickr.com/photos/auntiep/17135231/http://flickr.com/photos/einsame_spitze/406992131/http://flickr.com/photos/beija-flor/63758047/http://flickr.com/photos/amerune/174617912/http://flickr.com/photos/hungry_i/47938311/http://flickr.com/photos/santos/13952912/http://flickr.com/photos/supermietzi/179962496/http://flickr.com/photos/traveller2020/206931940/http://flickr.com/photos/ko_an/318906221/
http://flickr.com/photos/ryangreenberg/57722319/http://flickr.com/photos/benandliz/11065337/http://flickr.com/photos/gaspi/12944421/http://flickr.com/photos/thomashawk/221827536/http://flickr.com/photos/brianboulos/7707518/http://flickr.com/photos/ross/28330560/http://flickr.com/photos/emdot/45249090/http://flickr.com/photos/farhang/428136695/http://flickr.com/photos/belljar/67877047/http://flickr.com/photos/pulpolux/34545782/http://flickr.com/photos/monkeyc/107979135/http://flickr.com/photos/pedrosimoes7/449314732/http://flickr.com/photos/dincordero/405452471/http://flickr.com/photos/andidfl/203883534/http://flickr.com/photos/ivanomak/434387836/http://flickr.com/photos/nrvica/23858419/http://flickr.com/photos/thespeak/137012632/
![Page 60: Introduction to Active Record - Silicon Valley Ruby Conference 2007](https://reader034.fdocuments.in/reader034/viewer/2022052418/58f9ab9c760da3da068b8571/html5/thumbnails/60.jpg)
Introduction to Active RecordEvan ‘Rabble’ Henshaw-Plath
[email protected] - Yahoo! Brickhouseanarchogeek.com - testingrails.com
Questions?