SlideShare a Scribd company logo
1 of 56
Download to read offline
Introduction to ActiveRecord ,[object Object],[object Object]
Rails ActiveRecord ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Definition © Vita Rara, Inc. Active Record: An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. -Martin Fowler, Patterns of Enterprise Application Architecture (page 160)
Rails ActiveRecord ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
A Leaky Abstraction ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Fundamentals ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
ActiveRecord Model Example © Vita Rara, Inc. create_table  &quot;persons&quot;   do  |t|  t.string :first_name, last_name t.timestamps  end class  Person < ActiveRecord::Base end p = Person.new p.first_name = ‘Mark’ p.last_name = ‘Menard’ p.save
Working with Legacy Schemas ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
CRUD: Create, Read, Update, Delete ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
ActiveRecord::Base.new © Vita Rara, Inc. # Instantiate a new Person, which can be persisted. p  =  Person. new p.save # Instantiate a new Person, with attributes set based on a # Map, which can be persisted. p  =  Person. new (:first_name =>  'Mark' , :last_name =>  'Menard' ) p.save
ActiveRecord::Base.create © Vita Rara, Inc. # Immediated create a record in the database. p  =  Person.create(:first_name =>  'Mark' , :last_name =>  'Menard' ) # This sets the attributes and calls #save on the instance.
Finding Models ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Advanced Finding ,[object Object],© Vita Rara, Inc. User.find(:all,  :conditions => [ “login  =   ?  AND password  =   ?” , login, password], :limit =>  10 , :offset =>  10 , :order =>  'login' , :joins =>  'accounts on user.account_id = accounts.id' )
Advanced Finding (con’t) ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Eager Loading: Avoid N+1 Issue © Vita Rara, Inc. <%  # Don't put code like this in your view. This is for illustration only! # Find and display order summary of all pending orders for an account. orders  =  Order.find_pending_by_account(current_account) %> <% orders.each  do  |order| -%> <%= render :partial =>  'order_header'  %> <!-- This fires off a query for each order! BAD BAD BAD --> <% order.line_items.each  do  |line_item| -%> <%= render :partial =>  'line_item'  %> <%  end  -%> <%  end  -%> <%  # Better would be orders  =  Order.find_pending_by_account(current_account,  :include => [ :line_items ]) %>
Updating Models © Vita Rara, Inc. user  =  User.find( 1 ) user.first_name  =  ‘Mark’ user.save # returns true on success user.last_name  =  ‘Menard’ user.save! # throws an exception if it fails # Immediately update the attributes and call #save # returns true on success user.update_attributes(:first_name =>  'John' ,  :last_name =>  'Doe' ) # Immediately update the attributes and call #save! # throws an exception on failure. user.update_attributes!(:password =>  ‘abccd1234’ )
Transactions ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
ActiveRecord Associations
ActiveRecord Associations ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Association Methods ,[object Object],[object Object],[object Object],© Vita Rara, Inc.
ActiveRecord Association Examples © Vita Rara, Inc. # Has Many class  Order < ActiveRecord::Base has_many :order_line_items end class  OrderLineItem < ActiveRecord::Base belongs_to :order end # Has One class  Party < ActiveRecord::Base has_one :login_credential end class  LoginCredential < ActiveRecord::Base belongs_to :party end
has_many & belongs_to ,[object Object],[object Object],© Vita Rara, Inc. class  Order < ActiveRecord::Base   has_many :line_items end class  LineItem < ActiveRecord::Base   belongs_to :order end create_table :orders  do  |t|   t.string :number end create_table :line_items  do  |t|   t.integer :order_id end
Has Many Examples © Vita Rara, Inc. has_many :comments, :order =>  &quot;posted_on&quot;   has_many :comments, :include => :author  has_many :people, :class_name =>  &quot;Person&quot; ,    :conditions =>  &quot;deleted = 0&quot; , :order =>  &quot;name&quot;   has_many :tracks, :order =>  &quot;position&quot; , :dependent => :destroy  has_many :comments, :dependent => :nullify  has_many :tags, :as => :taggable  has_many :subscribers, :through => :subscriptions, :source => :user  has_many :subscribers, :class_name =>  &quot;Person&quot; , :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'
has_many Methods © Vita Rara, Inc. class  Firm   has_many :clients end firm  =  Firm.find( 1 ) firm.clients firm.clients <<   firm.clients.delete  firm.clients =   firm.client_ids  firm.client_ids =   firm.clients.clear  firm.clients.empty? firm.clients.count  firm.clients.find firm.clients.build(:first_name =>  'Mark' ) # Like Party.new(:firm_id => firm.id) firm.clients.create(:first_name =>  'Mark' ) # Like Party.create(:firm_id => firm.id)
has_and_belongs_to_many ,[object Object],© Vita Rara, Inc. create_table :categories_posts, :id => false  do    t.column :category_id, :integer, :null => false    t.column :post_id, :integer, :null => false  end   class  Product < ActiveRecord::Base   has_and_belongs_to_many :categories end class  Category < ActiveRecord::Base   has_and_belongs_to_many :products end product  =  Product.find_by_name(“Mac Book Pro”) category  =  Category.find_by_name(“Laptops”)  product.categories.count # => 0  category.products.count # => 0  product.categories  <<  category  product.categories.count # => 1  category.products.count # => 1
Join Models vs. has_and_belongs_to_many ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
has_many :foos, :through => :bars ,[object Object],© Vita Rara, Inc. class  Blog < ActiveRecord::Base   has_many :subscriptions   has_many :users, :through => :subscriptions end class  User < ActiveRecord::Base has_many :subscriptions has_many :blogs, :through => :subscriptions end class  Subscription < ActiveRecord::Base   belongs_to :blog   belongs_to :user end
Polymorphic Associations ,[object Object],© Vita Rara, Inc. class  Person < ActiveRecord::Base   has_one :address, :as => :addressable end class  Company < ActiveRecord::Base   has_one :address, :as => :addressable end class  Address < ActiveRecord::Base   belongs_to :addressable, :polymorphic => true end create_table :addresses  do  |t|   # ...   t.integer :addressable_id   t.string  :addressable_type end
ActiveRecord Validations ,[object Object]
Validation ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Validation Callbacks ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Validation Callbacks (cont) © Vita Rara, Inc. class  Person < ActiveRecord::Base  def   validate   puts “validate invoked”  end   def   validate_on_create   puts “validate_on_create invoked”  end   def   validate_on_update   puts “validate_on_update invoked”  end   end   peter  =  Person.create(:name => “Peter”)  # => peter.validate and peter.validate_on_create invoked  peter.last_name  =  “Forsberg”  peter.save # => peter.validate_on_update invoked
Declarative Validations © Vita Rara, Inc. Rails contains a large number of declarative validations that are applied to classes by convention. Declarative validations free developers from the drudgery of most model validation.
validates_presence_of ,[object Object],© Vita Rara, Inc. class  Person < ActiveRecord::Base   validates_presence_of :first_name   validates_presence_of :last_name end p  =  Person. new p.valid? #=> false p.first_name  =   'Mark' p.last_name  =   'Menard' p.valid? #=> true
validates_uniqueness_of ,[object Object],[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base belongs_to :account   validates_uniqueness_of :login, :scope => [ :account ] end account = Account.find(1) user_1  =  account.users.create(:login =>  'mark' ) user_2  =  account.users.create!(:login =>  'mark' ) #=> Throws InvalidRecord exceptoion
validates_numericality_of ,[object Object],[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base   validates_numericality_of :number, :integer_only => true end User.create!(:number =>  'some number' ) #=> Throws Invalid
validates_length_of ,[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base   validates_length_of :login, :within =>  3 .. 20   validates_length_of :password, :is =>  8   validates_length_of :name, :minimum =>  3 end
validates_format_of ,[object Object],[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base   validates_format_of :email, :with =>  /^[]+$/ end
validates_inclusion_of & validates_exclusion_of ,[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base   validates_inclusion_of :gender, :in =>  %w( male female ) ,  :message =>  &quot;Oh really....&quot; validates_exclusion_of :login, :in =>  %w( root admin super ) ,  :message =>  &quot;Tisk tisk...&quot; end
validates_associated ,[object Object],© Vita Rara, Inc. class  User < ActiveRecord::Base   belongs_to :account   validates_associated :account, :on => :create end class  Account < ActiveRecord::Base   validates_presence_of :name end user  =  User. new (:login =>  'mark' , :name =>  'Mark Menard' ) user.account  =  Account. new  # invalid missing name user.save! #=> Throws RecordInvalid exception.
Other Declarative Validations ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc. You can also create your own declarative validations that match your problem domain.
Using Validation Callbacks ,[object Object],[object Object],[object Object],© Vita Rara, Inc. class  Account   validate :does_domain_exist     private     def   does_domain_exist   Resolv.getaddress(self.domain_name)   rescue   errors.add(:domain_name,  'Domain name does not exist.' )   end end
Using Validation Callbacks ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Model Life Cycle
New Model Callbacks ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Existing Model Callbacks ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Destroy Model Callbacks ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Callback Use Cases ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Cleaning up Attributes Prior to Saving © Vita Rara, Inc. class  CreditCard   before_validation :cleanup_number     private     def   cleanup_number   self.number  =  number.gsub( /[^0-9]/ ,  &quot;&quot; ) true  # I like to be explicit   end end
Observers
Observers ,[object Object],[object Object],[object Object],© Vita Rara, Inc.
Creating an Audit Trail with an Observer © Vita Rara, Inc. # in config/environment.rb config.active_record_observers  =  [ :auditor ] # in auditor.rb class  Auditor < ActiveRecord::Observer   observe User     def   after_create  (model)   log_info( &quot;New #{model.class.name} created.&quot; , model)   end     def   after_update  (model)   log_info( &quot;Update #{model.class.name}&quot; , model)   end     def   after_destroy  (model)   log_info( &quot;Destroy #{model.class.name}&quot; , model)   end     private     def   log_info  (model, info)   log.info(info)   log.info(model.inspect)   end end
Shameless Self Promotion
Ruby and Rails Training ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Ruby on Rails Consulting ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.
Contact Information ,[object Object],[object Object],[object Object],[object Object],© Vita Rara, Inc.

More Related Content

What's hot

What's hot (20)

Laravel Tutorial PPT
Laravel Tutorial PPTLaravel Tutorial PPT
Laravel Tutorial PPT
 
HTML Semantic Elements
HTML Semantic ElementsHTML Semantic Elements
HTML Semantic Elements
 
Javascript basics
Javascript basicsJavascript basics
Javascript basics
 
Javascript
JavascriptJavascript
Javascript
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Html
HtmlHtml
Html
 
HTML5: features with examples
HTML5: features with examplesHTML5: features with examples
HTML5: features with examples
 
Html Intro2
Html Intro2Html Intro2
Html Intro2
 
Html
HtmlHtml
Html
 
Eye catching HTML BASICS tips: Learn easily
Eye catching HTML BASICS tips: Learn easilyEye catching HTML BASICS tips: Learn easily
Eye catching HTML BASICS tips: Learn easily
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
Cascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) helpCascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) help
 
Html5 semantics
Html5 semanticsHtml5 semantics
Html5 semantics
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 
Document Object Model
Document Object ModelDocument Object Model
Document Object Model
 
JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
 
Html tutorials
Html tutorialsHtml tutorials
Html tutorials
 
jQuery - Chapter 1 - Introduction
 jQuery - Chapter 1 - Introduction jQuery - Chapter 1 - Introduction
jQuery - Chapter 1 - Introduction
 
Document Object Model
Document Object ModelDocument Object Model
Document Object Model
 
HTML5 Form Validation
HTML5 Form ValidationHTML5 Form Validation
HTML5 Form Validation
 

Similar to Intro to Rails ActiveRecord

Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails Mohit Jain
 
Boston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsBoston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsJohn Brunswick
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-Ting Cheng
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?brynary
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on RailsMark Menard
 
Extending MySQL Enterprise Monitor
Extending MySQL Enterprise MonitorExtending MySQL Enterprise Monitor
Extending MySQL Enterprise MonitorMark Leith
 
DynamicRecord Presentation
DynamicRecord PresentationDynamicRecord Presentation
DynamicRecord Presentationlinoj
 
Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8Nicolas Thon
 
NHibernate (The ORM For .NET Platform)
NHibernate (The ORM For .NET Platform)NHibernate (The ORM For .NET Platform)
NHibernate (The ORM For .NET Platform)Samnang Chhun
 
Debugging and Error handling
Debugging and Error handlingDebugging and Error handling
Debugging and Error handlingSuite Solutions
 
Jasig Rubyon Rails
Jasig Rubyon RailsJasig Rubyon Rails
Jasig Rubyon RailsPaul Pajo
 
Compass Framework
Compass FrameworkCompass Framework
Compass FrameworkLukas Vlcek
 
Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On RailsWen-Tien Chang
 
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishSven Haiges
 
Intro Open Social and Dashboards
Intro Open Social and DashboardsIntro Open Social and Dashboards
Intro Open Social and DashboardsAtlassian
 
WordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big wordsWordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big wordsTomAuger
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Rabble .
 
Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009bturnbull
 

Similar to Intro to Rails ActiveRecord (20)

Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails
 
Boston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on RailsBoston Computing Review - Ruby on Rails
Boston Computing Review - Ruby on Rails
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
 
Extending MySQL Enterprise Monitor
Extending MySQL Enterprise MonitorExtending MySQL Enterprise Monitor
Extending MySQL Enterprise Monitor
 
DynamicRecord Presentation
DynamicRecord PresentationDynamicRecord Presentation
DynamicRecord Presentation
 
Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8Nhibernatethe Orm For Net Platform 1226744632929962 8
Nhibernatethe Orm For Net Platform 1226744632929962 8
 
NHibernate (The ORM For .NET Platform)
NHibernate (The ORM For .NET Platform)NHibernate (The ORM For .NET Platform)
NHibernate (The ORM For .NET Platform)
 
Debugging and Error handling
Debugging and Error handlingDebugging and Error handling
Debugging and Error handling
 
Jasig Rubyon Rails
Jasig Rubyon RailsJasig Rubyon Rails
Jasig Rubyon Rails
 
Compass Framework
Compass FrameworkCompass Framework
Compass Framework
 
Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On Rails
 
Framework
FrameworkFramework
Framework
 
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
 
Intro Open Social and Dashboards
Intro Open Social and DashboardsIntro Open Social and Dashboards
Intro Open Social and Dashboards
 
WordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big wordsWordPress development paradigms, idiosyncrasies and other big words
WordPress development paradigms, idiosyncrasies and other big words
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
 
Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009Rails 2.3 and Rack - NHRuby Feb 2009
Rails 2.3 and Rack - NHRuby Feb 2009
 

More from Mark Menard

Let's Do Some Upfront Design - WindyCityRails 2014
Let's Do Some Upfront Design - WindyCityRails 2014Let's Do Some Upfront Design - WindyCityRails 2014
Let's Do Some Upfront Design - WindyCityRails 2014Mark Menard
 
A Tour of Wyriki
A Tour of WyrikiA Tour of Wyriki
A Tour of WyrikiMark Menard
 
Small Code - RailsConf 2014
Small Code - RailsConf 2014Small Code - RailsConf 2014
Small Code - RailsConf 2014Mark Menard
 
Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014Mark Menard
 
Write Small Things (Code)
Write Small Things (Code)Write Small Things (Code)
Write Small Things (Code)Mark Menard
 
JRuby 6 Years in Production
JRuby 6 Years in ProductionJRuby 6 Years in Production
JRuby 6 Years in ProductionMark Menard
 
Conference of Grand Masters Tech Talk 2013
Conference of Grand Masters Tech Talk 2013Conference of Grand Masters Tech Talk 2013
Conference of Grand Masters Tech Talk 2013Mark Menard
 
Startup Lessons Learned
Startup Lessons LearnedStartup Lessons Learned
Startup Lessons LearnedMark Menard
 
Mobile Platforms and App Development
Mobile Platforms and App DevelopmentMobile Platforms and App Development
Mobile Platforms and App DevelopmentMark Menard
 
Ruby on Rails Training - Module 2
Ruby on Rails Training - Module 2Ruby on Rails Training - Module 2
Ruby on Rails Training - Module 2Mark Menard
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Mark Menard
 
Introduction to Ruby
Introduction to RubyIntroduction to Ruby
Introduction to RubyMark Menard
 
Behavior Driven Development with Rails
Behavior Driven Development with RailsBehavior Driven Development with Rails
Behavior Driven Development with RailsMark Menard
 
JRuby in a Java World
JRuby in a Java WorldJRuby in a Java World
JRuby in a Java WorldMark Menard
 

More from Mark Menard (14)

Let's Do Some Upfront Design - WindyCityRails 2014
Let's Do Some Upfront Design - WindyCityRails 2014Let's Do Some Upfront Design - WindyCityRails 2014
Let's Do Some Upfront Design - WindyCityRails 2014
 
A Tour of Wyriki
A Tour of WyrikiA Tour of Wyriki
A Tour of Wyriki
 
Small Code - RailsConf 2014
Small Code - RailsConf 2014Small Code - RailsConf 2014
Small Code - RailsConf 2014
 
Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014
 
Write Small Things (Code)
Write Small Things (Code)Write Small Things (Code)
Write Small Things (Code)
 
JRuby 6 Years in Production
JRuby 6 Years in ProductionJRuby 6 Years in Production
JRuby 6 Years in Production
 
Conference of Grand Masters Tech Talk 2013
Conference of Grand Masters Tech Talk 2013Conference of Grand Masters Tech Talk 2013
Conference of Grand Masters Tech Talk 2013
 
Startup Lessons Learned
Startup Lessons LearnedStartup Lessons Learned
Startup Lessons Learned
 
Mobile Platforms and App Development
Mobile Platforms and App DevelopmentMobile Platforms and App Development
Mobile Platforms and App Development
 
Ruby on Rails Training - Module 2
Ruby on Rails Training - Module 2Ruby on Rails Training - Module 2
Ruby on Rails Training - Module 2
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1
 
Introduction to Ruby
Introduction to RubyIntroduction to Ruby
Introduction to Ruby
 
Behavior Driven Development with Rails
Behavior Driven Development with RailsBehavior Driven Development with Rails
Behavior Driven Development with Rails
 
JRuby in a Java World
JRuby in a Java WorldJRuby in a Java World
JRuby in a Java World
 

Intro to Rails ActiveRecord

  • 1.
  • 2.
  • 3. Definition © Vita Rara, Inc. Active Record: An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. -Martin Fowler, Patterns of Enterprise Application Architecture (page 160)
  • 4.
  • 5.
  • 6.
  • 7. ActiveRecord Model Example © Vita Rara, Inc. create_table &quot;persons&quot; do |t| t.string :first_name, last_name t.timestamps end class Person < ActiveRecord::Base end p = Person.new p.first_name = ‘Mark’ p.last_name = ‘Menard’ p.save
  • 8.
  • 9.
  • 10. ActiveRecord::Base.new © Vita Rara, Inc. # Instantiate a new Person, which can be persisted. p = Person. new p.save # Instantiate a new Person, with attributes set based on a # Map, which can be persisted. p = Person. new (:first_name => 'Mark' , :last_name => 'Menard' ) p.save
  • 11. ActiveRecord::Base.create © Vita Rara, Inc. # Immediated create a record in the database. p = Person.create(:first_name => 'Mark' , :last_name => 'Menard' ) # This sets the attributes and calls #save on the instance.
  • 12.
  • 13.
  • 14.
  • 15. Eager Loading: Avoid N+1 Issue © Vita Rara, Inc. <% # Don't put code like this in your view. This is for illustration only! # Find and display order summary of all pending orders for an account. orders = Order.find_pending_by_account(current_account) %> <% orders.each do |order| -%> <%= render :partial => 'order_header' %> <!-- This fires off a query for each order! BAD BAD BAD --> <% order.line_items.each do |line_item| -%> <%= render :partial => 'line_item' %> <% end -%> <% end -%> <% # Better would be orders = Order.find_pending_by_account(current_account, :include => [ :line_items ]) %>
  • 16. Updating Models © Vita Rara, Inc. user = User.find( 1 ) user.first_name = ‘Mark’ user.save # returns true on success user.last_name = ‘Menard’ user.save! # throws an exception if it fails # Immediately update the attributes and call #save # returns true on success user.update_attributes(:first_name => 'John' , :last_name => 'Doe' ) # Immediately update the attributes and call #save! # throws an exception on failure. user.update_attributes!(:password => ‘abccd1234’ )
  • 17.
  • 19.
  • 20.
  • 21. ActiveRecord Association Examples © Vita Rara, Inc. # Has Many class Order < ActiveRecord::Base has_many :order_line_items end class OrderLineItem < ActiveRecord::Base belongs_to :order end # Has One class Party < ActiveRecord::Base has_one :login_credential end class LoginCredential < ActiveRecord::Base belongs_to :party end
  • 22.
  • 23. Has Many Examples © Vita Rara, Inc. has_many :comments, :order => &quot;posted_on&quot; has_many :comments, :include => :author has_many :people, :class_name => &quot;Person&quot; , :conditions => &quot;deleted = 0&quot; , :order => &quot;name&quot; has_many :tracks, :order => &quot;position&quot; , :dependent => :destroy has_many :comments, :dependent => :nullify has_many :tags, :as => :taggable has_many :subscribers, :through => :subscriptions, :source => :user has_many :subscribers, :class_name => &quot;Person&quot; , :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'
  • 24. has_many Methods © Vita Rara, Inc. class Firm has_many :clients end firm = Firm.find( 1 ) firm.clients firm.clients << firm.clients.delete firm.clients = firm.client_ids firm.client_ids = firm.clients.clear firm.clients.empty? firm.clients.count firm.clients.find firm.clients.build(:first_name => 'Mark' ) # Like Party.new(:firm_id => firm.id) firm.clients.create(:first_name => 'Mark' ) # Like Party.create(:firm_id => firm.id)
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32. Validation Callbacks (cont) © Vita Rara, Inc. class Person < ActiveRecord::Base def validate puts “validate invoked” end def validate_on_create puts “validate_on_create invoked” end def validate_on_update puts “validate_on_update invoked” end end peter = Person.create(:name => “Peter”) # => peter.validate and peter.validate_on_create invoked peter.last_name = “Forsberg” peter.save # => peter.validate_on_update invoked
  • 33. Declarative Validations © Vita Rara, Inc. Rails contains a large number of declarative validations that are applied to classes by convention. Declarative validations free developers from the drudgery of most model validation.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49. Cleaning up Attributes Prior to Saving © Vita Rara, Inc. class CreditCard before_validation :cleanup_number private def cleanup_number self.number = number.gsub( /[^0-9]/ , &quot;&quot; ) true # I like to be explicit end end
  • 51.
  • 52. Creating an Audit Trail with an Observer © Vita Rara, Inc. # in config/environment.rb config.active_record_observers = [ :auditor ] # in auditor.rb class Auditor < ActiveRecord::Observer observe User def after_create (model) log_info( &quot;New #{model.class.name} created.&quot; , model) end def after_update (model) log_info( &quot;Update #{model.class.name}&quot; , model) end def after_destroy (model) log_info( &quot;Destroy #{model.class.name}&quot; , model) end private def log_info (model, info) log.info(info) log.info(model.inspect) end end
  • 54.
  • 55.
  • 56.

Editor's Notes

  1. This definition supposes a relational data store. The active record pattern would not apply to document oriented systems such as CouchDB, Mongo, and other No-SQL databases, as they tend to store aggregates.
  2. I rarely use these options. :select can lead to confusion if you select columns from more than one table because the returned objects will be read-only. I have yet to find a common use case for :group
  3. Many times complex views will want to be backed by a custom finder to avoid N+1 issues. I usually place these in a finder module mixed into my model class to keep the model class clean.
  4. This is where we begin joining models to other models to reflect the domain space.
  5. I very rarely use this type of association. I find that my join models eventually begin to a
  6. To halt the chain return false. To continue return true.