Active Record Association (2), Season 2

1,449 views
1,365 views

Published on

This is a Keynote slide about the "ActiveRecord Association (2)"

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,449
On SlideShare
0
From Embeds
0
Number of Embeds
226
Actions
Shares
0
Downloads
34
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Active Record Association (2), Season 2

    1. 1. Ror lab. season 2 - the 9th round - Active RecordAssociations (2) November 3rd, 2012 Hyoseong Choi
    2. 2. Association Optionsbelongs_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. 3. Association Optionsbelongs_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. 4. Association Optionsbelongs_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. 5. Association Optionsbelongs_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. 6. Association Optionsbelongs_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. 7. Association Optionsbelongs_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. 8. Association Optionsbelongs_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. 9. Association Optionsbelongs_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. 10. Common Options• :autosave• :class_name• :conditions• :foreign_key• :include• :readonly• :select• :validate
    11. 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. 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. 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. 14. - common options - :class_name class Order < ActiveRecord::Base   belongs_to :customer, :class_name => "Patron" end
    15. 15. - common options - :conditions class Order < ActiveRecord::Base   belongs_to :customer, :conditions => "active = 1" end
    16. 16. - common options - :foreign_key class Order < ActiveRecord::Base   belongs_to :customer, :class_name => "Patron",     :foreign_key => "patron_id" end
    17. 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. 18. - common options - :readonly class Customer < ActiveRecord::Base   has_many :orders, :readonly => true end
    19. 19. - common options - :select class Order < ActiveRecord::Base   belongs_to :customer, :select => "name, profile, group_id" end
    20. 20. - common options - :validate class Order < ActiveRecord::Base   belongs_to :customer, :validate => true end
    21. 21. Common has_ Options has_one / has_many• :as• :order* (also, included in HABTM)• :primary_key• :source• :source_type• :through
    22. 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. 23. - common has_ options - :order class Post < ActiveRecord::Base   has_many :comments, :order => ”updated_at” end •also, in HABTM
    24. 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. 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. 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. 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. 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. 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. 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. 31. Common _many Options has_many / HABTM• :counter_sql• :extend• :finder_sql• :group• :limit• :offset• :uniq
    32. 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. 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. 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. 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. 36. - common _many options - :extend class Customer < ActiveRecord::Base   has_many :orders,     :extend => [FindRecentExtension, FindActiveExtension] end
    37. 37. - common _many options - * 3 AP accessors • proxy_association.owner • proxy_association.reflection • proxy_association.target AP* : Association Proxy
    38. 38. - common _many options - :group class Customer < ActiveRecord::Base   has_many :line_items, :through => :orders, :group => "orders.id" end
    39. 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. 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. 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. 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. 43. Special Options• belongs_to • :counter_cache • :polymorphic • :touch• HABTM • :association_foreign_key • :delete_sql • :insert_sql • :join_table
    44. 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. 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. 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. 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. 48. Association Callbacks• in the lifecycle of a collection • before_add • after_add • before_remove • after_remove
    49. 49. Association Callbacksclass Customer < ActiveRecord::Base  has_many :orders, :before_add => :check_credit_limit   def check_credit_limit(order)    ...  endendclass 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
    50. 50. Summary• http://jonathanhui.com/ruby-rails-3-model- association
    51. 51. 감사합니다.
    52. 52.   ROR Lab.

    ×