Active Record Association (2), Season 2

  • 1,047 views
Uploaded on

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

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,047
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
26
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    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

Transcript

  • 1. Ror lab. season 2 - the 9th round - Active RecordAssociations (2) November 3rd, 2012 Hyoseong Choi
  • 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. 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. 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. 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. 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. 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. 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. 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. 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 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. Summary• http://jonathanhui.com/ruby-rails-3-model- association
  • 51. 감사합니다.
  • 52.    ROR Lab.