SlideShare a Scribd company logo
The 10th Round of ROR Lab.



Active Record
Query Interface(2)

        April 7th, 2012

       Hyoseong Choi
         ROR Lab.
Short Review


               ROR Lab.
Query Interface(1)
  - How to retrieve data from DB -
Bi-directional Associations
 :inverse_of
  class Customer < ActiveRecord::Base
    has_many :orders, :inverse_of => :customer
  end
   
  class Order < ActiveRecord::Base
    belongs_to :customer, :inverse_of => :orders
  end
  ---------------------------------------------------
  c = Customer.first
  o = c.orders.first
  c.first_name == o.customer.first_name # => true
  c.first_name = 'Manny'
  c.first_name == o.customer.first_name # => true




                                                    ROR Lab.
Overriding
          Conditions
                       - reorder -
 class Post < ActiveRecord::Base
   ..
   ..
   has_many :comments, :order => 'posted_at DESC'
 end
  



SELECT * FROM posts WHERE id = 10 ORDER BY name

SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC


                                                       ROR Lab.
Locking Records
    for Update
• To prevent “race conditions”
• To ensure “atomic updates”
• Two locking mechanisms
  ‣ Optimistic Locking : version control
  ‣ Pessimistic Locking : DB lock

                                       ROR Lab.
Optimistic Locking
• “lock_version” in DB table (default to 0)
• set_locking_column to change column name
  c1 = Client.find(1)
  c2 = Client.find(1)
   
  c1.first_name = "Michael"
  c1.save # increments the lock_version column
   
  c2.name = "should fail"




                                                 ROR Lab.
Joining Tables
           - Using Array/Hash of Named Associations -

                                        only with INNER JOIN
class Category < ActiveRecord::Base
  has_many :posts
end
 
class Post < ActiveRecord::Base       • Multiple Associations
  belongs_to :category
  has_many :comments
  has_many :tags
end                                       Post.joins(:category, :comments)
 
class Comment < ActiveRecord::Base
  belongs_to :post
  has_one :guest                        SELECT posts.* FROM posts
end
 
                                          INNER JOIN categories
class Guest < ActiveRecord::Base           ON posts.category_id = categories.id
  belongs_to :comment                     INNER JOIN comments
end                                        ON comments.post_id = posts.id
 
class Tag < ActiveRecord::Base          “return all posts that have a category and at least one comment”
  belongs_to :post
end

                                                                                  ROR Lab.
Joining Tables
           - Using Array/Hash of Named Associations -

                                        only with INNER JOIN
class Category < ActiveRecord::Base
  has_many :posts
end
 
class Post < ActiveRecord::Base       • Nested Associations(Single Level)
  belongs_to :category
  has_many :comments
  has_many :tags
end                                       Post.joins(:comments => :guest)
 
class Comment < ActiveRecord::Base
  belongs_to :post
  has_one :guest                        SELECT posts.* FROM posts
end
 
                                          INNER JOIN comments
class Guest < ActiveRecord::Base           ON comments.post_id = posts.id
  belongs_to :comment                     INNER JOIN guests
end                                        ON guests.comment_id = comments.id
 
class Tag < ActiveRecord::Base
  belongs_to :post
                                        “return all posts that have a comment made by a guest”
end

                                                                               ROR Lab.
Query Interface(2)
  - How to retrieve data from DB -
Eager Loading
     Associations
           : as few queries as possible

N + 1 queries problem


 clients = Client.limit(10)
  
 clients.each do |client|
   puts client.address.postcode




                                          ROR Lab.
Eager Loading
      Associations
             : as few queries as possible

Solution to N + 1 queries problem                     Only 2 queries

 clients = Client.includes(:address).limit(10)
  
 clients.each do |client|
   puts client.address.postcode



SELECT * FROM clients LIMIT 10
SELECT addresses.* FROM addresses
  WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))

                                                              ROR Lab.
Eager Loading
      Associations
- Eager Loading Multiple Associations -
 Array of Multiple Associations




 Nested Associations Hash


 Category.includes(
  :posts => [{:comments => :guest}, :tags]).find(1)



                                                     ROR Lab.
Eager Loading
         Associations
- Conditions on Eager Loaded Associations -

      conditional “joins” > conditional “includes”


   Post.includes(:comments)
     .where("comments.visible", true)


  SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5
  FROM "posts"
  LEFT OUTER JOIN "comments"
  ON "comments"."post_id" = "posts"."id"
  WHERE (comments.visible = 1)


                                                                       ROR Lab.
Eager Loading
         Associations
- Conditions on Eager Loaded Associations -
                      INNER JOIN                             LEFT OUTER JOIN
      conditional “joins” > conditional “includes”


   Post.includes(:comments)
     .where("comments.visible", true)


  SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5
  FROM "posts"
  LEFT OUTER JOIN "comments"
  ON "comments"."post_id" = "posts"."id"
  WHERE (comments.visible = 1)


                                                                       ROR Lab.
Scopes

• To specify ARel queries
• Referenced as method calls on the
  association objects or model
• finder methods in a scope
• return an ActiveRecord::Relation object
                                       ROR Lab.
Scopes

class Post < ActiveRecord::Base
  scope :published, where(:published => true)
end
                              ARel query




                                                ROR Lab.
Scopes
chainable
class Post < ActiveRecord::Base
  scope :published,
  where(:published => true).joins(:category)
end




chainable within scopes
class Post < ActiveRecord::Base
  scope :published, where(:published => true)
  scope :published_and_commented,
published.and(self.arel_table[:comments_count].gt(0))




                                                        ROR Lab.
Scopes
                To call the scope

Post.published # => [published posts]

category = Category.first
category.posts.published
# => [published posts belonging to this category]




                                                    ROR Lab.
Scopes
                Working with times

class Post < ActiveRecord::Base
  scope :last_week,
  lambda { where("created_at < ?", Time.zone.now ) }
end     a lambda so that the scope is evaluated every time




                                                             ROR Lab.
Scopes
             Passing in arguments
class Post < ActiveRecord::Base
  scope :1_week_before,
  lambda { |time| where("created_at < ?", time) }
end




class Post < ActiveRecord::Base
  def self.1_week_before(time)
    where("created_at < ?", time)
  end
                      ***What about “as a class method” ?

                                                     ROR Lab.
Scopes
                   Passing in arguments
      class Post < ActiveRecord::Base
        scope :1_week_before,
        lambda { |time| where("created_at < ?", time) }
      end




           le
       eab
    erclass Post < ActiveRecord::Base
  ef
pr      def self.1_week_before(time)
          where("created_at < ?", time)
        end
                            ***What about “as a class method” ?

                                                           ROR Lab.
Scopes
Passing in arguments




                       ROR Lab.
Scopes
            Working with Scopes


client = Client.find_by_first_name("Ryan")




                                           ROR Lab.
Scopes
         Applying a default scope


class Client < ActiveRecord::Base
  default_scope where("removed_at IS NULL")




SELECT * FROM clients WHERE removed_at IS NULL



                                                 ROR Lab.
Scopes
   Removing all scopes




       Especially useful,
when escaping the default_scope



                                  ROR Lab.
Dynamic Finders
• Model.find_by_attribute_name
• Model.find_all_by_attribute_name
• Model.find_last_by_attribute_name
• Model.find_by_attribute_name!
• Model.find_by_attr1_and_attr2
Rails 3.1 < Argument Error on missing fields

                                      ROR Lab.
Find or build
      a new object

• first_or_create
• first_or_create!      Exception on invalid

• first_or_initialize

                                         ROR Lab.
Find or build
            a new object
• first_or_create
  Client.where(:first_name => 'Andy').first_or_create(:locked =>
  false)
  # => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at:
  "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">


  Client.find_or_create_by_first_name(:first_name =>
  "Andy", :locked => false)


SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1
BEGIN
INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES
('2011-08-30 05:22:57', 'Andy', 0, NULL, '2011-08-30 05:22:57')
COMMIT

                                                                                        ROR Lab.
Find or build
          a new object
• first_or_create!
 class Client < ActiveRecord::Base
  validates :orders_count, :presence => true
 end

 Client.where(:first_name => 'Andy').first_or_create!(:locked =>
 false)
 # => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank




                                                                           ROR Lab.
Find or build
          a new object
• first_or_initialize
 nick = Client.where(:first_name =>
 'Nick').first_or_initialize(:locked => false)
 # => <Client id: nil, first_name: "Nick", orders_count: 0, locked: false,
 created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
  
 SELECT * FROM clients WHERE (clients.first_name = 'Nick') LIMIT 1
 nick.persisted?
 # => false
 nick.new_record?
 # => true
 nick.save
 # => true


persisted? vs new_record?                                               ROR Lab.
Finding by SQL
 : return an array of objects
 where each object indicates a record

Client.find_by_sql("SELECT * FROM clients
  INNER JOIN orders ON clients.id = orders.client_id




cf. connection.select_all
       an array of hash

                                                       ROR Lab.
select_all
 : return an array of hash
 where each hash indicates a record

Client.connection.select_all("SELECT * FROM clients WHERE id =




cf. find_by_sql -> instantiates objects


                                                          ROR Lab.
pluck
 To query a single column from the underlying table of a model
 To return an array of values


Client.where(:active => true).pluck(:id)
# SELECT id FROM clients WHERE active = 1
 
Client.uniq.pluck(:role)




Client.select(:id).map { |c| c.id }

   Client.pluck(:id)



                                                         ROR Lab.
Existence of
           Objects
Client.exists?(1)

Client.exists?(1,2,3)
# or
Client.exists?([1,2,3])

Client.where(:first_name => 'Ryan').exists?




cf. find method
                                             ROR Lab.
Existence of
         Objects
# via a model
Post.any?
Post.many?
 
# via a named scope
Post.recent.any?
Post.recent.many?
 
# via a relation
Post.where(:published => true).any?
Post.where(:published => true).many?
 
# via an association
Post.first.categories.any?



                                       ROR Lab.
Calculations
 Client.count
 # SELECT count(*) AS count_all FROM clients

 Client.where(:first_name => 'Ryan').count
 # SELECT count(*) AS count_all FROM clients WHERE (first_name =
 'Ryan')

 Client.includes("orders").where(:first_name => 'Ryan', :orders



SELECT count(DISTINCT clients.id) AS count_all FROM clients
  LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE
  (clients.first_name = 'Ryan' AND orders.status = 'received')




                                                                 ROR Lab.
Calculations
Client.count(:age)

Client.average("orders_count")

Client.minimum("age")

Client.maximum("age")




                                 ROR Lab.
Running EXPLAIN
              a pretty printing that emulates the one of the database shells



              User.where(:id => 1).joins(:posts).explain




EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id`
=1
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
|  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |             |
|  1 | SIMPLE      | posts | ALL   | NULL          | NULL    | NULL    | NULL  |    1 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
2 rows in set (0.00 sec)



under MySQL

                                                                                                 ROR Lab.
Running EXPLAIN
               a pretty printing that emulates the one of the database shells



               User.where(:id => 1).joins(:posts).explain




EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1
                                  QUERY PLAN
------------------------------------------------------------------------------
 Nested Loop Left Join  (cost=0.00..37.24 rows=8 width=0)
   Join Filter: (posts.user_id = users.id)
   ->  Index Scan using users_pkey on users  (cost=0.00..8.27 rows=1 width=4)
         Index Cond: (id = 1)
   ->  Seq Scan on posts  (cost=0.00..28.88 rows=8 width=4)
         Filter: (posts.user_id = 1)
(6 rows)



under PostgreSQL
                                                                                                        ROR Lab.
Running EXPLAIN
                                        Eager Loading


          User.where(:id => 1).includes(:posts).explain


 EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1
 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 |  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 1 row in set (0.00 sec)
  
 EXPLAIN for: SELECT `posts`.* FROM `posts`  WHERE `posts`.`user_id` IN (1)
 +----+-------------+-------+------+---------------+------+---------+------+------+-------------
 +
 | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
 +----+-------------+-------+------+---------------+------+---------+------+------+-------------
 +
 |  1 | SIMPLE      | posts | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where |



under MySQL                                                                        ROR Lab.
Running EXPLAIN
              Automatic EXPLAIN

To set the threshold in seconds
config.active_record.auto_explain_threshold_in_seconds



• disables automatic EXPLAIN => nil or no AR logger
• Development mode => default, 0.5 sec
• Test mode => nil
• Production mode => nil

                                                        ROR Lab.
Running EXPLAIN
      Disabling Automatic EXPLAIN

To be selectively silenced with
 ActiveRecord::Base.silence_auto_explain do
   # no automatic EXPLAIN is triggered here




• useful for queries are slow but fine
  : a heavyweight report of a admin interface


                                                ROR Lab.
감사합니다.

More Related Content

What's hot

Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
GreggPollack
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
Workhorse Computing
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011Alexander Klimetschek
 
XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話
Takehito Tanabe
 
iOS Behavior-Driven Development
iOS Behavior-Driven DevelopmentiOS Behavior-Driven Development
iOS Behavior-Driven Development
Brian Gesiak
 
Rails and the Apache SOLR Search Engine
Rails and the Apache SOLR Search EngineRails and the Apache SOLR Search Engine
Rails and the Apache SOLR Search Engine
David Keener
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
Mindfire Solutions
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
José Paumard
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Supa fast Ruby + Rails
Supa fast Ruby + RailsSupa fast Ruby + Rails
Supa fast Ruby + Rails
Jean-Baptiste Feldis
 
Laravel dokumentacja Restful API - swagger
Laravel dokumentacja Restful API - swaggerLaravel dokumentacja Restful API - swagger
Laravel dokumentacja Restful API - swagger
Laravel Poland MeetUp
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
Workhorse Computing
 
Designing CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsDesigning CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIs
Neil Crookes
 
Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2
Sumy PHP User Grpoup
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
Alex Soto
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Zend framework
Zend frameworkZend framework
Zend framework
Prem Shankar
 

What's hot (20)

Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011CQ5 QueryBuilder - .adaptTo(Berlin) 2011
CQ5 QueryBuilder - .adaptTo(Berlin) 2011
 
XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
iOS Behavior-Driven Development
iOS Behavior-Driven DevelopmentiOS Behavior-Driven Development
iOS Behavior-Driven Development
 
Rails and the Apache SOLR Search Engine
Rails and the Apache SOLR Search EngineRails and the Apache SOLR Search Engine
Rails and the Apache SOLR Search Engine
 
Getting Started-with-Laravel
Getting Started-with-LaravelGetting Started-with-Laravel
Getting Started-with-Laravel
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Supa fast Ruby + Rails
Supa fast Ruby + RailsSupa fast Ruby + Rails
Supa fast Ruby + Rails
 
Laravel dokumentacja Restful API - swagger
Laravel dokumentacja Restful API - swaggerLaravel dokumentacja Restful API - swagger
Laravel dokumentacja Restful API - swagger
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Designing CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIsDesigning CakePHP plugins for consuming APIs
Designing CakePHP plugins for consuming APIs
 
Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2Service approach for development REST API in Symfony2
Service approach for development REST API in Symfony2
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Zend framework
Zend frameworkZend framework
Zend framework
 

Similar to Active Record Query Interface (2), Season 1

ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2RORLAB
 
ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1
RORLAB
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
RORLAB
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
Wayne Carter
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
rstankov
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
Raimonds Simanovskis
 
Pourquoi ruby et rails déchirent
Pourquoi ruby et rails déchirentPourquoi ruby et rails déchirent
Pourquoi ruby et rails déchirent
Nicolas Ledez
 
Active Record Form Helpers, Season 1
Active Record Form Helpers, Season 1Active Record Form Helpers, Season 1
Active Record Form Helpers, Season 1
RORLAB
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Rabble .
 
Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
Ruby on Rails 2.1 What's New
Ruby on Rails 2.1 What's NewRuby on Rails 2.1 What's New
Ruby on Rails 2.1 What's New
Libin Pan
 
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
Rabble .
 
Ruby on Rails 中級者を目指して - 大場寧子
Ruby on Rails 中級者を目指して - 大場寧子Ruby on Rails 中級者を目指して - 大場寧子
Ruby on Rails 中級者を目指して - 大場寧子
Yasuko Ohba
 
Timothy N. Tsvetkov, Rails 3.1
Timothy N. Tsvetkov, Rails 3.1Timothy N. Tsvetkov, Rails 3.1
Timothy N. Tsvetkov, Rails 3.1
Evil Martians
 
Carlosbrando Rubyonrails21 En
Carlosbrando Rubyonrails21 EnCarlosbrando Rubyonrails21 En
Carlosbrando Rubyonrails21 EnCasey Bradford
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
Sociable
 
Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
Alina Vilk
 
KSP intro
KSP introKSP intro
KSP intro
Jintin Lin
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to MissJava Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
Andres Almiray
 

Similar to Active Record Query Interface (2), Season 1 (20)

ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2
 
ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Rails on Oracle 2011
Rails on Oracle 2011Rails on Oracle 2011
Rails on Oracle 2011
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
Pourquoi ruby et rails déchirent
Pourquoi ruby et rails déchirentPourquoi ruby et rails déchirent
Pourquoi ruby et rails déchirent
 
Active Record Form Helpers, Season 1
Active Record Form Helpers, Season 1Active Record Form Helpers, Season 1
Active Record Form Helpers, Season 1
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
 
Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子Ruby on Rails ステップアップ講座 - 大場寧子
Ruby on Rails ステップアップ講座 - 大場寧子
 
Ruby on Rails 2.1 What's New
Ruby on Rails 2.1 What's NewRuby on Rails 2.1 What's New
Ruby on Rails 2.1 What's New
 
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
 
Ruby on Rails 中級者を目指して - 大場寧子
Ruby on Rails 中級者を目指して - 大場寧子Ruby on Rails 中級者を目指して - 大場寧子
Ruby on Rails 中級者を目指して - 大場寧子
 
Timothy N. Tsvetkov, Rails 3.1
Timothy N. Tsvetkov, Rails 3.1Timothy N. Tsvetkov, Rails 3.1
Timothy N. Tsvetkov, Rails 3.1
 
Carlosbrando Rubyonrails21 En
Carlosbrando Rubyonrails21 EnCarlosbrando Rubyonrails21 En
Carlosbrando Rubyonrails21 En
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
 
Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
 
KSP intro
KSP introKSP intro
KSP intro
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to MissJava Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 

More from RORLAB

Getting Started with Rails (4)
Getting Started with Rails (4) Getting Started with Rails (4)
Getting Started with Rails (4)
RORLAB
 
Getting Started with Rails (3)
Getting Started with Rails (3) Getting Started with Rails (3)
Getting Started with Rails (3)
RORLAB
 
Getting Started with Rails (2)
Getting Started with Rails (2)Getting Started with Rails (2)
Getting Started with Rails (2)
RORLAB
 
Getting Started with Rails (1)
Getting Started with Rails (1)Getting Started with Rails (1)
Getting Started with Rails (1)
RORLAB
 
Self join in active record association
Self join in active record associationSelf join in active record association
Self join in active record association
RORLAB
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on Rails
RORLAB
 
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
RORLAB
 
Active Support Core Extension (3)
Active Support Core Extension (3)Active Support Core Extension (3)
Active Support Core Extension (3)RORLAB
 
Active Support Core Extension (2)
Active Support Core Extension (2)Active Support Core Extension (2)
Active Support Core Extension (2)RORLAB
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
RORLAB
 
Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2RORLAB
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2RORLAB
 
Active Record Association (2), Season 2
Active Record Association (2), Season 2Active Record Association (2), Season 2
Active Record Association (2), Season 2
RORLAB
 
ActiveRecord Association (1), Season 2
ActiveRecord Association (1), Season 2ActiveRecord Association (1), Season 2
ActiveRecord Association (1), Season 2
RORLAB
 
ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2
RORLAB
 
ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2
RORLAB
 
Rails Database Migration, Season 2
Rails Database Migration, Season 2Rails Database Migration, Season 2
Rails Database Migration, Season 2
RORLAB
 
Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2
RORLAB
 
Getting started with Rails (3), Season 2
Getting started with Rails (3), Season 2Getting started with Rails (3), Season 2
Getting started with Rails (3), Season 2
RORLAB
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2
RORLAB
 

More from RORLAB (20)

Getting Started with Rails (4)
Getting Started with Rails (4) Getting Started with Rails (4)
Getting Started with Rails (4)
 
Getting Started with Rails (3)
Getting Started with Rails (3) Getting Started with Rails (3)
Getting Started with Rails (3)
 
Getting Started with Rails (2)
Getting Started with Rails (2)Getting Started with Rails (2)
Getting Started with Rails (2)
 
Getting Started with Rails (1)
Getting Started with Rails (1)Getting Started with Rails (1)
Getting Started with Rails (1)
 
Self join in active record association
Self join in active record associationSelf join in active record association
Self join in active record association
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on Rails
 
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
레일스가이드 한글번역 공개프로젝트 RORLabGuides 소개
 
Active Support Core Extension (3)
Active Support Core Extension (3)Active Support Core Extension (3)
Active Support Core Extension (3)
 
Active Support Core Extension (2)
Active Support Core Extension (2)Active Support Core Extension (2)
Active Support Core Extension (2)
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
 
Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
 
Active Record Association (2), Season 2
Active Record Association (2), Season 2Active Record Association (2), Season 2
Active Record Association (2), Season 2
 
ActiveRecord Association (1), Season 2
ActiveRecord Association (1), Season 2ActiveRecord Association (1), Season 2
ActiveRecord Association (1), Season 2
 
ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2
 
ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2
 
Rails Database Migration, Season 2
Rails Database Migration, Season 2Rails Database Migration, Season 2
Rails Database Migration, Season 2
 
Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2Getting started with Rails (4), Season 2
Getting started with Rails (4), Season 2
 
Getting started with Rails (3), Season 2
Getting started with Rails (3), Season 2Getting started with Rails (3), Season 2
Getting started with Rails (3), Season 2
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2
 

Recently uploaded

Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 

Recently uploaded (20)

Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 

Active Record Query Interface (2), Season 1

  • 1. The 10th Round of ROR Lab. Active Record Query Interface(2) April 7th, 2012 Hyoseong Choi ROR Lab.
  • 2. Short Review ROR Lab.
  • 3. Query Interface(1) - How to retrieve data from DB -
  • 4. Bi-directional Associations :inverse_of class Customer < ActiveRecord::Base   has_many :orders, :inverse_of => :customer end   class Order < ActiveRecord::Base   belongs_to :customer, :inverse_of => :orders end --------------------------------------------------- c = Customer.first o = c.orders.first c.first_name == o.customer.first_name # => true c.first_name = 'Manny' c.first_name == o.customer.first_name # => true ROR Lab.
  • 5. Overriding Conditions - reorder - class Post < ActiveRecord::Base   ..   ..   has_many :comments, :order => 'posted_at DESC' end   SELECT * FROM posts WHERE id = 10 ORDER BY name SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC ROR Lab.
  • 6. Locking Records for Update • To prevent “race conditions” • To ensure “atomic updates” • Two locking mechanisms ‣ Optimistic Locking : version control ‣ Pessimistic Locking : DB lock ROR Lab.
  • 7. Optimistic Locking • “lock_version” in DB table (default to 0) • set_locking_column to change column name c1 = Client.find(1) c2 = Client.find(1)   c1.first_name = "Michael" c1.save # increments the lock_version column   c2.name = "should fail" ROR Lab.
  • 8. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • Multiple Associations   belongs_to :category   has_many :comments   has_many :tags end Post.joins(:category, :comments)   class Comment < ActiveRecord::Base   belongs_to :post   has_one :guest SELECT posts.* FROM posts end     INNER JOIN categories class Guest < ActiveRecord::Base ON posts.category_id = categories.id   belongs_to :comment   INNER JOIN comments end ON comments.post_id = posts.id   class Tag < ActiveRecord::Base “return all posts that have a category and at least one comment”   belongs_to :post end ROR Lab.
  • 9. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • Nested Associations(Single Level)   belongs_to :category   has_many :comments   has_many :tags end Post.joins(:comments => :guest)   class Comment < ActiveRecord::Base   belongs_to :post   has_one :guest SELECT posts.* FROM posts end     INNER JOIN comments class Guest < ActiveRecord::Base ON comments.post_id = posts.id   belongs_to :comment   INNER JOIN guests end ON guests.comment_id = comments.id   class Tag < ActiveRecord::Base   belongs_to :post “return all posts that have a comment made by a guest” end ROR Lab.
  • 10. Query Interface(2) - How to retrieve data from DB -
  • 11. Eager Loading Associations : as few queries as possible N + 1 queries problem clients = Client.limit(10)   clients.each do |client|   puts client.address.postcode ROR Lab.
  • 12. Eager Loading Associations : as few queries as possible Solution to N + 1 queries problem Only 2 queries clients = Client.includes(:address).limit(10)   clients.each do |client|   puts client.address.postcode SELECT * FROM clients LIMIT 10 SELECT addresses.* FROM addresses   WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10)) ROR Lab.
  • 13. Eager Loading Associations - Eager Loading Multiple Associations - Array of Multiple Associations Nested Associations Hash Category.includes( :posts => [{:comments => :guest}, :tags]).find(1) ROR Lab.
  • 14. Eager Loading Associations - Conditions on Eager Loaded Associations - conditional “joins” > conditional “includes” Post.includes(:comments) .where("comments.visible", true) SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible = 1) ROR Lab.
  • 15. Eager Loading Associations - Conditions on Eager Loaded Associations - INNER JOIN LEFT OUTER JOIN conditional “joins” > conditional “includes” Post.includes(:comments) .where("comments.visible", true) SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible = 1) ROR Lab.
  • 16. Scopes • To specify ARel queries • Referenced as method calls on the association objects or model • finder methods in a scope • return an ActiveRecord::Relation object ROR Lab.
  • 17. Scopes class Post < ActiveRecord::Base   scope :published, where(:published => true) end ARel query ROR Lab.
  • 18. Scopes chainable class Post < ActiveRecord::Base   scope :published, where(:published => true).joins(:category) end chainable within scopes class Post < ActiveRecord::Base   scope :published, where(:published => true)   scope :published_and_commented, published.and(self.arel_table[:comments_count].gt(0)) ROR Lab.
  • 19. Scopes To call the scope Post.published # => [published posts] category = Category.first category.posts.published # => [published posts belonging to this category] ROR Lab.
  • 20. Scopes Working with times class Post < ActiveRecord::Base   scope :last_week, lambda { where("created_at < ?", Time.zone.now ) } end a lambda so that the scope is evaluated every time ROR Lab.
  • 21. Scopes Passing in arguments class Post < ActiveRecord::Base   scope :1_week_before, lambda { |time| where("created_at < ?", time) } end class Post < ActiveRecord::Base   def self.1_week_before(time)     where("created_at < ?", time)   end ***What about “as a class method” ? ROR Lab.
  • 22. Scopes Passing in arguments class Post < ActiveRecord::Base   scope :1_week_before, lambda { |time| where("created_at < ?", time) } end le eab erclass Post < ActiveRecord::Base ef pr   def self.1_week_before(time)     where("created_at < ?", time)   end ***What about “as a class method” ? ROR Lab.
  • 24. Scopes Working with Scopes client = Client.find_by_first_name("Ryan") ROR Lab.
  • 25. Scopes Applying a default scope class Client < ActiveRecord::Base   default_scope where("removed_at IS NULL") SELECT * FROM clients WHERE removed_at IS NULL ROR Lab.
  • 26. Scopes Removing all scopes Especially useful, when escaping the default_scope ROR Lab.
  • 27. Dynamic Finders • Model.find_by_attribute_name • Model.find_all_by_attribute_name • Model.find_last_by_attribute_name • Model.find_by_attribute_name! • Model.find_by_attr1_and_attr2 Rails 3.1 < Argument Error on missing fields ROR Lab.
  • 28. Find or build a new object • first_or_create • first_or_create! Exception on invalid • first_or_initialize ROR Lab.
  • 29. Find or build a new object • first_or_create Client.where(:first_name => 'Andy').first_or_create(:locked => false) # => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27"> Client.find_or_create_by_first_name(:first_name => "Andy", :locked => false) SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1 BEGIN INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES ('2011-08-30 05:22:57', 'Andy', 0, NULL, '2011-08-30 05:22:57') COMMIT ROR Lab.
  • 30. Find or build a new object • first_or_create! class Client < ActiveRecord::Base validates :orders_count, :presence => true end Client.where(:first_name => 'Andy').first_or_create!(:locked => false) # => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank ROR Lab.
  • 31. Find or build a new object • first_or_initialize nick = Client.where(:first_name => 'Nick').first_or_initialize(:locked => false) # => <Client id: nil, first_name: "Nick", orders_count: 0, locked: false, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">   SELECT * FROM clients WHERE (clients.first_name = 'Nick') LIMIT 1 nick.persisted? # => false nick.new_record? # => true nick.save # => true persisted? vs new_record? ROR Lab.
  • 32. Finding by SQL : return an array of objects where each object indicates a record Client.find_by_sql("SELECT * FROM clients   INNER JOIN orders ON clients.id = orders.client_id cf. connection.select_all an array of hash ROR Lab.
  • 33. select_all : return an array of hash where each hash indicates a record Client.connection.select_all("SELECT * FROM clients WHERE id = cf. find_by_sql -> instantiates objects ROR Lab.
  • 34. pluck To query a single column from the underlying table of a model To return an array of values Client.where(:active => true).pluck(:id) # SELECT id FROM clients WHERE active = 1   Client.uniq.pluck(:role) Client.select(:id).map { |c| c.id } Client.pluck(:id) ROR Lab.
  • 35. Existence of Objects Client.exists?(1) Client.exists?(1,2,3) # or Client.exists?([1,2,3]) Client.where(:first_name => 'Ryan').exists? cf. find method ROR Lab.
  • 36. Existence of Objects # via a model Post.any? Post.many?   # via a named scope Post.recent.any? Post.recent.many?   # via a relation Post.where(:published => true).any? Post.where(:published => true).many?   # via an association Post.first.categories.any? ROR Lab.
  • 37. Calculations Client.count # SELECT count(*) AS count_all FROM clients Client.where(:first_name => 'Ryan').count # SELECT count(*) AS count_all FROM clients WHERE (first_name = 'Ryan') Client.includes("orders").where(:first_name => 'Ryan', :orders SELECT count(DISTINCT clients.id) AS count_all FROM clients   LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE   (clients.first_name = 'Ryan' AND orders.status = 'received') ROR Lab.
  • 39. Running EXPLAIN a pretty printing that emulates the one of the database shells User.where(:id => 1).joins(:posts).explain EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `posts` ON `posts`.`user_id` = `users`.`id` WHERE `users`.`id` =1 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra       | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ |  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |             | |  1 | SIMPLE      | posts | ALL   | NULL          | NULL    | NULL    | NULL  |    1 | Using where | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ 2 rows in set (0.00 sec) under MySQL ROR Lab.
  • 40. Running EXPLAIN a pretty printing that emulates the one of the database shells User.where(:id => 1).joins(:posts).explain EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" WHERE "users"."id" = 1                                   QUERY PLAN ------------------------------------------------------------------------------  Nested Loop Left Join  (cost=0.00..37.24 rows=8 width=0)    Join Filter: (posts.user_id = users.id)    ->  Index Scan using users_pkey on users  (cost=0.00..8.27 rows=1 width=4)          Index Cond: (id = 1)    ->  Seq Scan on posts  (cost=0.00..28.88 rows=8 width=4)          Filter: (posts.user_id = 1) (6 rows) under PostgreSQL ROR Lab.
  • 41. Running EXPLAIN Eager Loading User.where(:id => 1).includes(:posts).explain EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ |  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec)   EXPLAIN for: SELECT `posts`.* FROM `posts`  WHERE `posts`.`user_id` IN (1) +----+-------------+-------+------+---------------+------+---------+------+------+------------- + | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       | +----+-------------+-------+------+---------------+------+---------+------+------+------------- + |  1 | SIMPLE      | posts | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where | under MySQL ROR Lab.
  • 42. Running EXPLAIN Automatic EXPLAIN To set the threshold in seconds config.active_record.auto_explain_threshold_in_seconds • disables automatic EXPLAIN => nil or no AR logger • Development mode => default, 0.5 sec • Test mode => nil • Production mode => nil ROR Lab.
  • 43. Running EXPLAIN Disabling Automatic EXPLAIN To be selectively silenced with ActiveRecord::Base.silence_auto_explain do   # no automatic EXPLAIN is triggered here • useful for queries are slow but fine : a heavyweight report of a admin interface ROR Lab.
  • 45.   ROR Lab.

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n