SlideShare a Scribd company logo
1 of 51
Ror lab. season 2
   - the 9th round -


  Active Record
Associations (2)

   November 3rd, 2012

     Hyoseong Choi
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Association Options
belongs_to options   has_one options   has_many options   HABTM options
• :autosave          • :autosave       • :autosave        • :autosave
• :class_name        • :class_name     • :class_name      • :class_name
• :conditions        • :conditions     • :conditions      • :conditions
• :foreign_key       • :foreign_key    • :foreign_key     • :foreign_key
• :include           • :include        • :include         • :include
• :readonly          • :readonly       • :readonly        • :readonly
• :select            • :select         • :select          • :select
• :validate          • :validate       • :validate        • :validate
• :dependent         • :as             • :as              • :order
• :counter_cache     • :order          • :order           • :counter_sql
• :polymorphic       • :primary_key    • :primary_key     • :extend
• :touch             • :source         • :source          • :finder_sql
                     • :source_type    • :source_type     • :group
                     • :through        • :through         • :limit
                     • :dependent      • :counter_sql     • :offset
                                       • :extend          • :uniq
                                       • :finder_sql      • :association_foreign_key
                                       • :group           • :delete_sql
                                       • :limit           • :insert_sql
                                       • :offset          • :join_table
                                       • :uniq
                                       • :dependent
Common Options
• :autosave
• :class_name
• :conditions
• :foreign_key
• :include
• :readonly
• :select
• :validate
- common options -

                     :autosave
       • No declaration (default)
           : new children are saved when their parent
           is saved
       • :autosave => true
           : all children is saved, no matter whether
           they are new records
       • :autosave => false
           : any children is not saved
- common options -

                                    :autosave
          class Post
           has_one :author, :autosave => true
          end
                                                                               has_one
          post = Post.find(1)
          post.title   # => "The current global position of migrating ducks"
          post.author.name # => "alloy"

          post.title = "On the migration of ducks"
          post.author.name = "Eloy Duran"

          post.save
          post.reload
          post.title   # => "On the migration of ducks"
          post.author.name # => "Eloy Duran"

          post.author.mark_for_destruction
          post.author.marked_for_destruction? # => true

          id = post.author.id
          Author.find_by_id(id).nil? # => false

          post.save
          post.reload.author # => nil

          Author.find_by_id(id).nil? # => true




               http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
- common options -                                 :autosave

                                                                           has_many
          class Post
            has_many :comments # :autosave option is no declared
          end

          post = Post.new(:title => 'ruby rocks')
          post.comments.build(:body => 'hello world')
          post.save # => saves both post and comment

          post = Post.create(:title => 'ruby rocks')
          post.comments.build(:body => 'hello world')
          post.save # => saves both post and comment

          post = Post.create(:title => 'ruby rocks')
          post.comments.create(:body => 'hello world')
          post.save # => saves both post and comment

          class Post
            has_many :comments, :autosave => true
          end

          post = Post.create(:title => 'ruby rocks')
          post.comments.create(:body => 'hello world')
          post.comments[0].body = 'hi everyone'
          post.save # => saves both post and comment, with 'hi everyone' as body

          post.comments.last.mark_for_destruction
          post.comments.last.marked_for_destruction? # => true
          post.comments.length # => 2

          id = post.comments.last.id
          Comment.find_by_id(id).nil? # => false

          post.save
          post.reload.comments.length # => 1

          Comment.find_by_id(id).nil? # => true
- common options -

                  :class_name

          class Order < ActiveRecord::Base
            belongs_to :customer, :class_name => "Patron"
          end
- common options -

                     :conditions

          class Order < ActiveRecord::Base
            belongs_to :customer, :conditions => "active = 1"
          end
- common options -

                 :foreign_key

          class Order < ActiveRecord::Base
            belongs_to :customer, :class_name => "Patron",
              :foreign_key => "patron_id"
          end
- common options -

                         :include
                   @line_item.order.customer

          class LineItem < ActiveRecord::Base
            belongs_to :order, :include => :customer
          end
           
          class Order < ActiveRecord::Base
            belongs_to :customer
            has_many :line_items
          end
           
          class Customer < ActiveRecord::Base
            has_many :orders
          end
- common options -

                      :readonly

          class Customer < ActiveRecord::Base
            has_many :orders, :readonly => true
          end
- common options -

                            :select
          class Order < ActiveRecord::Base
            belongs_to :customer,
                  :select => "name, profile, group_id"
          end
- common options -

                        :validate

          class Order < ActiveRecord::Base
            belongs_to :customer, :validate => true
          end
Common
        has_ Options
              has_one / has_many

• :as
• :order* (also, included in HABTM)
• :primary_key
• :source
• :source_type
• :through
- common has_ options -

                                   :as
          class Employee < ActiveRecord::Base
            has_many :pictures, :as => :imageable
          end
           
          class Product < ActiveRecord::Base
            has_many :pictures, :as => :imageable
          end

          class Picture < ActiveRecord::Base
            belongs_to :imageable, :polymorphic => true
          end
- common has_ options -

                             :order

          class Post < ActiveRecord::Base
            has_many :comments, :order => ”updated_at”
          end




          •also, in HABTM
- common has_ options -

               :primary_key
          class Customer < ActiveRecord::Base   default
            has_many :orders,
                :primary_key => "id",
                :foreign_key => "customer_id"




          class Customer < ActiveRecord::Base
            has_many :orders
                :primary_key => "order_id",
                :foreign_key => "patron_id"
- common has_ options -

               :primary_key
          class Order < ActiveRecord::Base                   default
            belongs_to :customer,
                  :primary_key => "id",
                  :foreign_key => "customer_id"




          class Order < ActiveRecord::Base
            belongs_to :customer, :class_name => "Patron",
                  :primary_key => "civil_no",
                  :foreign_key => "patron_id"
- common has_ options -

       :source & :source_type
          class Book < ActiveRecord::Base
           has_many :taggings
           has_many :tags, :through => :taggings
          end

          class Tag < ActiveRecord::Base
           has_many :taggings
           has_many :books, :through => :taggings
          end

          class Tagging < ActiveRecord::Base
           belongs_to :book
           belongs_to :tag
                                                    join model
          end


         - Basic many-to-many association format
- common has_ options -

       :source & :source_type
                                 class Movie < ActiveRecord::Base
                                   has_many :taggings, :as => :taggable
          class Book < ActiveRecord::Base
           has_many :taggings, :as has_many :tags, :through => :taggings
                                   => :taggable
                                 end
           has_many :tags, :through => :taggings
          end

          class Tagging < ActiveRecord::Base
           belongs_to :taggble, :polymorphic => true
           belongs_to :tag
          end

          class Tag < ActiveRecord::Base
           has_many :taggings
           has_many :taggables, :through => :taggings
          end


         - Polymorphic many-to-many association format
- common has_ options -

          :source & :source_type
  class Book < ActiveRecord::Base
   has_many :taggings, :as => :taggable         class Movie < ActiveRecord::Base
   has_many :tags, :through => :taggings         has_many :taggings, :as => :taggable
  end                                            has_many :tags, :through => :taggings
                                                end
  class Tagging < ActiveRecord::Base
   belongs_to :taggble, :polymorphic => true
   belongs_to :tag
  end


  class Tag < ActiveRecord::Base
   has_many :taggings
   has_many :taggables, :through => :taggings
   has_many :books, :source => :taggable, :source_type => “Book”, :through => :taggings
   has_many :movies, :source => :taggable, :source_type => “Movie”, :through => :taggings
  end


              - Polymorphic many-to-many association format
- common has_ options -

       :source & :source_type
          class Tag < ActiveRecord::Base
            has_many :taggings, :dependent => :destroy
            has_many :books, :through => :taggings, :source => :taggable, :source_type => "Book"
            has_many :movies, :through => :taggings, :source => :taggable, :source_type => "Movie"
          end

          class Tagging < ActiveRecord::Base
            belongs_to :taggable, :polymorphic => true
            belongs_to :tag
          end

          class Book < ActiveRecord::Base
            has_many :taggings, :as => :taggable
            has_many :tags, :through => :taggings
          end

          class Movie < ActiveRecord::Base
            has_many :taggings, :as => :taggable
            has_many :tags, :through => :taggings
          end




         - Polymorphic many-to-many association format
- common has_ options -

                        :through
          class Supplier < ActiveRecord::Base
            has_one :account
            has_one :account_history, :through => :account
          end
           
          class Account < ActiveRecord::Base
            belongs_to :supplier
            has_one :account_history
          end
           
          class AccountHistory < ActiveRecord::Base
            belongs_to :account
          end
Common
     _many Options
                 has_many / HABTM

• :counter_sql
• :extend
• :finder_sql
• :group
• :limit
• :offset
• :uniq
- common _many options -

                     :finder_sql
       class Person < ActiveRecord::Base
        has_many :subscribers,
                :class_name => "Person",
                :finder_sql => Proc.new {
          %Q{
            SELECT DISTINCT *
            FROM people p, post_subscriptions ps
            WHERE ps.post_id = #{id} AND ps.person_id = p.id
            ORDER BY p.first_name
          }
        }
- common _many options -

                  :counter_sql
       class Person < ActiveRecord::Base
        has_many :subscribers,
                :class_name => "Person",
                :counter_sql => Proc.new {
          %Q{
            SELECT DISTINCT *
            FROM people p, post_subscriptions ps
            WHERE ps.post_id = #{id} AND ps.person_id = p.id
            ORDER BY p.first_name
          }
        }
- common _many options -

                           :extend
      association proxy(or interface)

       class Customer < ActiveRecord::Base
         has_many :orders do
           def find_by_order_prefix(order_number)
             find_by_region_id(order_number[0..2])
           end
         end
- common _many options -

                          :extend
       module FindRecentExtension
         def find_recent
           where("created_at > ?", 5.days.ago)
         end
       end
        
       class Customer < ActiveRecord::Base
         has_many :orders, :extend => FindRecentExtension
       end
        
       class Supplier < ActiveRecord::Base
         has_many :deliveries, :extend => FindRecentExtension
- common _many options -

                             :extend
       class Customer < ActiveRecord::Base
         has_many :orders,
           :extend => [FindRecentExtension, FindActiveExtension]
       end
- common _many options -
                           *
            3 AP accessors

       • proxy_association.owner
       • proxy_association.reflection
       • proxy_association.target

       AP* : Association Proxy
- common _many options -

                            :group
       class Customer < ActiveRecord::Base
         has_many :line_items,
              :through => :orders,
              :group => "orders.id"
       end
- common _many options -

              :limit / :offset
       class Customer < ActiveRecord::Base
         has_many :recent_orders,
              :class_name => "Order",
              :order => "order_date DESC",
              :limit => 100
              :offset => 300
- common _many options -

                                 :uniq
       class Person < ActiveRecord::Base
         has_many :readings
         has_many :posts, :through => :readings
       end
        
       person = Person.create(:name => 'john')
       post   = Post.create(:name => 'a1')
       person.posts << post
       person.posts << post
       person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5,
       name: "a1">]
       Reading.all.inspect  # => [#<Reading id: 12, person_id: 5, post_id: 5>,
       #<Reading id: 13, person_id: 5, post_id: 5>]
- common _many options -

                                 :uniq
       class Person
         has_many :readings
         has_many :posts, :through => :readings, :uniq => true
       end
        
       person = Person.create(:name => 'honda')
       post   = Post.create(:name => 'a1')
       person.posts << post
       person.posts << post
       person.posts.inspect # => [#<Post id: 7, name: "a1">]
       Reading.all.inspect  # => [#<Reading id: 16, person_id: 7, post_id: 7>,
       #<Reading id: 17, person_id: 7, post_id: 7>]
Common
  one-way Options
         belongs_to / has_one / has_many
• :dependent
 class Comment < ActiveRecord::Base
   belongs_to :post, :dependent => :destroy
 end



 class Post < ActiveRecord::Base
   has_many :comments, :dependent => :destroy
 end
Special Options
• belongs_to
  • :counter_cache
  • :polymorphic
  • :touch
• HABTM
  • :association_foreign_key
  • :delete_sql
  • :insert_sql
  • :join_table
- special options for HABTM -

      :association_foreign_key

        class User < ActiveRecord::Base
          has_and_belongs_to_many :friends,
            :class_name => "User",
            :foreign_key => "this_user_id",
            :association_foreign_key => "other_user_id"




                         many-to-many self join
- special options for HABTM -

                     :delete_sql
        class Developer < ActiveRecord::Base
          has_and_belongs_to_many :active_projects,
            :join_table => 'developers_projects',
            :delete_sql =>
               "DELETE FROM developers_projects WHERE active=1
                AND developer_id = #{id}
                AND project_id = #{record.id}"
        end
- special options for HABTM -

                      :insert_sql
        class Developer < ActiveRecord::Base
          has_and_belongs_to_many :active_projects,
            :join_table => 'developers_projects',
            :insert_sql =>
               "INSERT INTO developers_projects
                VALUES(#{id},#{record.id})"
        end
- special options for HABTM -

                      :join_table
        class Category < ActiveRecord::Base
          has_and_belongs_to_many :products,
                         :join_table => “cats_prods”
        end
         
        class Product < ActiveRecord::Base
          has_and_belongs_to_many :categories,
                         :join_table => “cats_prods”




         default join table => “categories_products”
Association Callbacks

• in the lifecycle of a collection
 • before_add
 • after_add
 • before_remove
 • after_remove
Association Callbacks
class Customer < ActiveRecord::Base
  has_many :orders, :before_add => :check_credit_limit
 
  def check_credit_limit(order)
    ...
  end
end

class Customer < ActiveRecord::Base
  has_many :orders,
    :before_add =>
        [:check_credit_limit, :calculate_shipping_charges]
 
  def check_credit_limit(order)
    ...
  end
 
  def calculate_shipping_charges(order)
    ...
  end
Summary


• http://jonathanhui.com/ruby-rails-3-model-
  association
감사합니다.

More Related Content

More from RORLAB

Self join in active record association
Self join in active record associationSelf join in active record association
Self join in active record associationRORLAB
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsRORLAB
 
레일스가이드 한글번역 공개프로젝트 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 Controller Overview, Season 2
Action Controller Overview, Season 2Action Controller Overview, Season 2
Action Controller Overview, Season 2RORLAB
 
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
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2RORLAB
 
ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2RORLAB
 
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 2RORLAB
 
ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2ActiveRecord Callbacks & Observers, Season 2
ActiveRecord Callbacks & Observers, Season 2RORLAB
 
ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2ActiveRecord Validations, Season 2
ActiveRecord Validations, Season 2RORLAB
 
Rails Database Migration, Season 2
Rails Database Migration, Season 2Rails Database Migration, Season 2
Rails Database Migration, Season 2RORLAB
 
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 2RORLAB
 
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 2RORLAB
 
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 2RORLAB
 
Getting started with Rails (1), Season 2
Getting started with Rails (1), Season 2Getting started with Rails (1), Season 2
Getting started with Rails (1), Season 2RORLAB
 
Routing 2, Season 1
Routing 2, Season 1Routing 2, Season 1
Routing 2, Season 1RORLAB
 

More from RORLAB (20)

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 Controller Overview, Season 2
Action Controller Overview, Season 2Action Controller Overview, Season 2
Action Controller Overview, Season 2
 
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
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2
 
ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2ActiveRecord Query Interface (2), Season 2
ActiveRecord Query Interface (2), Season 2
 
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
 
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
 
Getting started with Rails (1), Season 2
Getting started with Rails (1), Season 2Getting started with Rails (1), Season 2
Getting started with Rails (1), Season 2
 
Routing 2, Season 1
Routing 2, Season 1Routing 2, Season 1
Routing 2, Season 1
 

Active Record Association (2), Season 2

  • 1. Ror lab. season 2 - the 9th round - Active Record Associations (2) November 3rd, 2012 Hyoseong Choi
  • 2. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 3. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 4. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 5. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 6. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 7. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 8. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 9. Association Options belongs_to options has_one options has_many options HABTM options • :autosave • :autosave • :autosave • :autosave • :class_name • :class_name • :class_name • :class_name • :conditions • :conditions • :conditions • :conditions • :foreign_key • :foreign_key • :foreign_key • :foreign_key • :include • :include • :include • :include • :readonly • :readonly • :readonly • :readonly • :select • :select • :select • :select • :validate • :validate • :validate • :validate • :dependent • :as • :as • :order • :counter_cache • :order • :order • :counter_sql • :polymorphic • :primary_key • :primary_key • :extend • :touch • :source • :source • :finder_sql • :source_type • :source_type • :group • :through • :through • :limit • :dependent • :counter_sql • :offset • :extend • :uniq • :finder_sql • :association_foreign_key • :group • :delete_sql • :limit • :insert_sql • :offset • :join_table • :uniq • :dependent
  • 10. Common Options • :autosave • :class_name • :conditions • :foreign_key • :include • :readonly • :select • :validate
  • 11. - common options - :autosave • No declaration (default) : new children are saved when their parent is saved • :autosave => true : all children is saved, no matter whether they are new records • :autosave => false : any children is not saved
  • 12. - common options - :autosave class Post has_one :author, :autosave => true end has_one post = Post.find(1) post.title # => "The current global position of migrating ducks" post.author.name # => "alloy" post.title = "On the migration of ducks" post.author.name = "Eloy Duran" post.save post.reload post.title # => "On the migration of ducks" post.author.name # => "Eloy Duran" post.author.mark_for_destruction post.author.marked_for_destruction? # => true id = post.author.id Author.find_by_id(id).nil? # => false post.save post.reload.author # => nil Author.find_by_id(id).nil? # => true http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
  • 13. - common options - :autosave has_many class Post has_many :comments # :autosave option is no declared end post = Post.new(:title => 'ruby rocks') post.comments.build(:body => 'hello world') post.save # => saves both post and comment post = Post.create(:title => 'ruby rocks') post.comments.build(:body => 'hello world') post.save # => saves both post and comment post = Post.create(:title => 'ruby rocks') post.comments.create(:body => 'hello world') post.save # => saves both post and comment class Post has_many :comments, :autosave => true end post = Post.create(:title => 'ruby rocks') post.comments.create(:body => 'hello world') post.comments[0].body = 'hi everyone' post.save # => saves both post and comment, with 'hi everyone' as body post.comments.last.mark_for_destruction post.comments.last.marked_for_destruction? # => true post.comments.length # => 2 id = post.comments.last.id Comment.find_by_id(id).nil? # => false post.save post.reload.comments.length # => 1 Comment.find_by_id(id).nil? # => true
  • 14. - common options - :class_name class Order < ActiveRecord::Base   belongs_to :customer, :class_name => "Patron" end
  • 15. - common options - :conditions class Order < ActiveRecord::Base   belongs_to :customer, :conditions => "active = 1" end
  • 16. - common options - :foreign_key class Order < ActiveRecord::Base   belongs_to :customer, :class_name => "Patron",     :foreign_key => "patron_id" end
  • 17. - common options - :include @line_item.order.customer class LineItem < ActiveRecord::Base   belongs_to :order, :include => :customer end   class Order < ActiveRecord::Base   belongs_to :customer   has_many :line_items end   class Customer < ActiveRecord::Base   has_many :orders end
  • 18. - common options - :readonly class Customer < ActiveRecord::Base   has_many :orders, :readonly => true end
  • 19. - common options - :select class Order < ActiveRecord::Base   belongs_to :customer, :select => "name, profile, group_id" end
  • 20. - common options - :validate class Order < ActiveRecord::Base   belongs_to :customer, :validate => true end
  • 21. Common has_ Options has_one / has_many • :as • :order* (also, included in HABTM) • :primary_key • :source • :source_type • :through
  • 22. - common has_ options - :as class Employee < ActiveRecord::Base   has_many :pictures, :as => :imageable end   class Product < ActiveRecord::Base   has_many :pictures, :as => :imageable end class Picture < ActiveRecord::Base   belongs_to :imageable, :polymorphic => true end
  • 23. - common has_ options - :order class Post < ActiveRecord::Base   has_many :comments, :order => ”updated_at” end •also, in HABTM
  • 24. - common has_ options - :primary_key class Customer < ActiveRecord::Base default   has_many :orders, :primary_key => "id", :foreign_key => "customer_id" class Customer < ActiveRecord::Base   has_many :orders :primary_key => "order_id", :foreign_key => "patron_id"
  • 25. - common has_ options - :primary_key class Order < ActiveRecord::Base default   belongs_to :customer, :primary_key => "id", :foreign_key => "customer_id" class Order < ActiveRecord::Base   belongs_to :customer, :class_name => "Patron", :primary_key => "civil_no", :foreign_key => "patron_id"
  • 26. - common has_ options - :source & :source_type class Book < ActiveRecord::Base has_many :taggings has_many :tags, :through => :taggings end class Tag < ActiveRecord::Base has_many :taggings has_many :books, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :book belongs_to :tag join model end - Basic many-to-many association format
  • 27. - common has_ options - :source & :source_type class Movie < ActiveRecord::Base has_many :taggings, :as => :taggable class Book < ActiveRecord::Base has_many :taggings, :as has_many :tags, :through => :taggings => :taggable end has_many :tags, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :taggble, :polymorphic => true belongs_to :tag end class Tag < ActiveRecord::Base has_many :taggings has_many :taggables, :through => :taggings end - Polymorphic many-to-many association format
  • 28. - common has_ options - :source & :source_type class Book < ActiveRecord::Base has_many :taggings, :as => :taggable class Movie < ActiveRecord::Base has_many :tags, :through => :taggings has_many :taggings, :as => :taggable end has_many :tags, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :taggble, :polymorphic => true belongs_to :tag end class Tag < ActiveRecord::Base has_many :taggings has_many :taggables, :through => :taggings has_many :books, :source => :taggable, :source_type => “Book”, :through => :taggings has_many :movies, :source => :taggable, :source_type => “Movie”, :through => :taggings end - Polymorphic many-to-many association format
  • 29. - common has_ options - :source & :source_type class Tag < ActiveRecord::Base has_many :taggings, :dependent => :destroy has_many :books, :through => :taggings, :source => :taggable, :source_type => "Book" has_many :movies, :through => :taggings, :source => :taggable, :source_type => "Movie" end class Tagging < ActiveRecord::Base belongs_to :taggable, :polymorphic => true belongs_to :tag end class Book < ActiveRecord::Base has_many :taggings, :as => :taggable has_many :tags, :through => :taggings end class Movie < ActiveRecord::Base has_many :taggings, :as => :taggable has_many :tags, :through => :taggings end - Polymorphic many-to-many association format
  • 30. - common has_ options - :through class Supplier < ActiveRecord::Base   has_one :account   has_one :account_history, :through => :account end   class Account < ActiveRecord::Base   belongs_to :supplier   has_one :account_history end   class AccountHistory < ActiveRecord::Base   belongs_to :account end
  • 31. Common _many Options has_many / HABTM • :counter_sql • :extend • :finder_sql • :group • :limit • :offset • :uniq
  • 32. - common _many options - :finder_sql class Person < ActiveRecord::Base has_many :subscribers, :class_name => "Person", :finder_sql => Proc.new { %Q{ SELECT DISTINCT * FROM people p, post_subscriptions ps WHERE ps.post_id = #{id} AND ps.person_id = p.id ORDER BY p.first_name } }
  • 33. - common _many options - :counter_sql class Person < ActiveRecord::Base has_many :subscribers, :class_name => "Person", :counter_sql => Proc.new { %Q{ SELECT DISTINCT * FROM people p, post_subscriptions ps WHERE ps.post_id = #{id} AND ps.person_id = p.id ORDER BY p.first_name } }
  • 34. - common _many options - :extend association proxy(or interface) class Customer < ActiveRecord::Base   has_many :orders do     def find_by_order_prefix(order_number)       find_by_region_id(order_number[0..2])     end   end
  • 35. - common _many options - :extend module FindRecentExtension   def find_recent     where("created_at > ?", 5.days.ago)   end end   class Customer < ActiveRecord::Base   has_many :orders, :extend => FindRecentExtension end   class Supplier < ActiveRecord::Base   has_many :deliveries, :extend => FindRecentExtension
  • 36. - common _many options - :extend class Customer < ActiveRecord::Base   has_many :orders,     :extend => [FindRecentExtension, FindActiveExtension] end
  • 37. - common _many options - * 3 AP accessors • proxy_association.owner • proxy_association.reflection • proxy_association.target AP* : Association Proxy
  • 38. - common _many options - :group class Customer < ActiveRecord::Base   has_many :line_items, :through => :orders, :group => "orders.id" end
  • 39. - common _many options - :limit / :offset class Customer < ActiveRecord::Base   has_many :recent_orders, :class_name => "Order",      :order => "order_date DESC", :limit => 100 :offset => 300
  • 40. - common _many options - :uniq class Person < ActiveRecord::Base   has_many :readings   has_many :posts, :through => :readings end   person = Person.create(:name => 'john') post   = Post.create(:name => 'a1') person.posts << post person.posts << post person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5, name: "a1">] Reading.all.inspect  # => [#<Reading id: 12, person_id: 5, post_id: 5>, #<Reading id: 13, person_id: 5, post_id: 5>]
  • 41. - common _many options - :uniq class Person   has_many :readings   has_many :posts, :through => :readings, :uniq => true end   person = Person.create(:name => 'honda') post   = Post.create(:name => 'a1') person.posts << post person.posts << post person.posts.inspect # => [#<Post id: 7, name: "a1">] Reading.all.inspect  # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>]
  • 42. Common one-way Options belongs_to / has_one / has_many • :dependent class Comment < ActiveRecord::Base   belongs_to :post, :dependent => :destroy end class Post < ActiveRecord::Base   has_many :comments, :dependent => :destroy end
  • 43. Special Options • belongs_to • :counter_cache • :polymorphic • :touch • HABTM • :association_foreign_key • :delete_sql • :insert_sql • :join_table
  • 44. - special options for HABTM - :association_foreign_key class User < ActiveRecord::Base   has_and_belongs_to_many :friends, :class_name => "User",     :foreign_key => "this_user_id",     :association_foreign_key => "other_user_id" many-to-many self join
  • 45. - special options for HABTM - :delete_sql class Developer < ActiveRecord::Base has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql => "DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}" end
  • 46. - special options for HABTM - :insert_sql class Developer < ActiveRecord::Base has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :insert_sql => "INSERT INTO developers_projects VALUES(#{id},#{record.id})" end
  • 47. - special options for HABTM - :join_table class Category < ActiveRecord::Base   has_and_belongs_to_many :products, :join_table => “cats_prods” end   class Product < ActiveRecord::Base   has_and_belongs_to_many :categories, :join_table => “cats_prods” default join table => “categories_products”
  • 48. Association Callbacks • in the lifecycle of a collection • before_add • after_add • before_remove • after_remove
  • 49. Association Callbacks class Customer < ActiveRecord::Base   has_many :orders, :before_add => :check_credit_limit     def check_credit_limit(order)     ...   end end class Customer < ActiveRecord::Base   has_many :orders,     :before_add => [:check_credit_limit, :calculate_shipping_charges]     def check_credit_limit(order)     ...   end     def calculate_shipping_charges(order)     ...   end
  • 52.   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
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n