Associations in Rails
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Associations in Rails

on

  • 11,886 views

This was the sixth speech of a three day Rails training I gave in Tulsa, OK in the spring 2010.

This was the sixth speech of a three day Rails training I gave in Tulsa, OK in the spring 2010.

Statistics

Views

Total Views
11,886
Views on SlideShare
11,874
Embed Views
12

Actions

Likes
14
Downloads
225
Comments
0

3 Embeds 12

http://www.slideshare.net 10
http://malditointer.net 1
https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />

Associations in Rails Presentation Transcript

  • 1. Associations Modeling database relationships with ActiveRecord
  • 2. Database Modeling The “relational” in relational database
  • 3. Database Types
  • 4. Database Types Rails was designed with a relational database bias
  • 5. Database Types Rails was designed with a relational database bias Though it can work with other tools, we will stick with this primary focus
  • 6. Database Types Rails was designed with a relational database bias Though it can work with other tools, we will stick with this primary focus ActiveRecord can work with the SQL these databases use to make queries
  • 7. Database Types Rails was designed with a relational database bias Though it can work with other tools, we will stick with this primary focus ActiveRecord can work with the SQL these databases use to make queries One of the ways it does that is to manage the relationships of data in separate tables
  • 8. Relationship Types
  • 9. Relationship Types There are only three types of relationships in SQL
  • 10. Relationship Types There are only three types of relationships in SQL One to one
  • 11. Relationship Types There are only three types of relationships in SQL One to one One to many
  • 12. Relationship Types There are only three types of relationships in SQL One to one One to many Many to many
  • 13. Relationship Types There are only three types of relationships in SQL One to one One to many Many to many This doesn’t really exist, but it can be simulated
  • 14. One to One users id first_name last_name 1 James Gray 2 Dana Gray photos id user_id path 1 1 /images/james.png
  • 15. One to One users id first_name last_name 1 James Gray 2 Dana Gray photos id user_id path 1 1 /images/james.png
  • 16. One to Many articles id title body comments 1 The CRUD … id article_id body 2 Associations … 1 1 First! 2 1 Tard. 3 1 Am not! 4 2 Viagra 5 2 Spam!
  • 17. One to Many articles id title body comments 1 The CRUD … id article_id body 2 Associations … 1 1 First! 2 1 Tard. 3 1 Am not! 4 2 Viagra 5 2 Spam!
  • 18. One to Many articles id title body comments 1 The CRUD … id article_id body 2 Associations … 1 1 First! 2 1 Tard. 3 1 Am not! 4 2 Viagra 5 2 Spam!
  • 19. photos Many to Many id path 1 /images/mac.jpg taggings 2 /images/pc.bmp id photo_id tag_id 1 1 1 tags id name 2 1 2 1 computer 3 1 3 2 sexy 4 2 4 3 lickable 4 junk
  • 20. photos Many to Many id path 1 /images/mac.jpg taggings 2 /images/pc.bmp id photo_id tag_id 1 1 1 tags id name 2 1 2 1 computer 3 1 3 2 sexy 4 2 4 3 lickable 4 junk
  • 21. photos Many to Many id path 1 /images/mac.jpg taggings 2 /images/pc.bmp id photo_id tag_id 1 1 1 tags id name 2 1 2 1 computer 3 1 3 2 sexy 4 2 4 3 lickable 4 junk
  • 22. Many to Many (Two Tables) followings users id follower_id followed_id id first_name last_name 1 1 4 1 James Gray 2 2 4 2 Dana Gray 3 3 1 3 Super Man 4 4 1 4 Bat Man 5 5 1 5 Spider Man
  • 23. Many to Many (Two Tables) followings users id follower_id followed_id id first_name last_name 1 1 4 1 James Gray 2 2 4 2 Dana Gray 3 3 1 3 Super Man 4 4 1 4 Bat Man 5 5 1 5 Spider Man
  • 24. Many to Many (Two Tables) followings users id follower_id followed_id id first_name last_name 1 1 4 1 James Gray 2 2 4 2 Dana Gray 3 3 1 3 Super Man 4 4 1 4 Bat Man 5 5 1 5 Spider Man
  • 25. Conventions at Work articles id title body 1 Unique … comments id article_id body 1 1 First!
  • 26. Conventions at Work Rails favors conventions articles id title body 1 Unique … comments id article_id body 1 1 First!
  • 27. Conventions at Work Rails favors conventions articles With associations: id title body 1 Unique … comments id article_id body 1 1 First!
  • 28. Conventions at Work Rails favors conventions articles With associations: id title body Auto-incremented ID 1 Unique … fields comments id article_id body 1 1 First!
  • 29. Conventions at Work Rails favors conventions articles With associations: id title body Auto-incremented ID 1 Unique … fields Table name is plural comments for the collection id article_id body 1 1 First!
  • 30. Conventions at Work Rails favors conventions articles With associations: id title body Auto-incremented ID 1 Unique … fields Table name is plural comments for the collection id article_id body Foreign key is a singular item plus _id 1 1 First!
  • 31. Associations, Rails Style Let’s turn those examples into real Rails code
  • 32. Rails Macros
  • 33. Rails Macros Use belongs_to() on the ID side of a one to one or one to many
  • 34. Rails Macros Use belongs_to() on the ID side of a one to one or one to many Use has_one() on the other side of a one to one
  • 35. Rails Macros Use belongs_to() on the ID side of a one to one or one to many Use has_one() on the other side of a one to one Use has_many() on the other side of a one to many
  • 36. Rails Macros Use belongs_to() on the ID side of a one to one or one to many Use has_one() on the other side of a one to one Use has_many() on the other side of a one to many Use two belongs_to() calls for the join model of a many to many
  • 37. Rails Macros Use belongs_to() on the ID side of a one to one or one to many Use has_one() on the other side of a one to one Use has_many() on the other side of a one to many Use two belongs_to() calls for the join model of a many to many Use has_many() and has_many(…, :through => …) for the data models of a many to many
  • 38. One to Many articles id title body comments 1 The CRUD … id article_id body 2 Associations … 1 1 First! 2 1 Tard. 3 1 Am not! 4 2 Viagra 5 2 Spam!
  • 39. One to Many An article has_many() comments
  • 40. class Article < ActiveRecord::Base has_many :comments end class Comment < ActiveRecord::Base belongs_to :article end One to Many An article has_many() comments
  • 41. Associated Models You can query through the association
  • 42. >> crud = Article.first => #<Article id: 1, title: "The CRUD", body: "...", …> >> crud.comments.count => 3 >> crud.comments => [#<Comment id: 1, article_id: 1, body: "First!", …>, #<Comment id: 2, article_id: 1, body: "Tard.", …>, #<Comment id: 3, article_id: 1, body: "Am not!", …>] >> crud.comments.last => #<Comment id: 3, article_id: 1, body: "Am not!", …> >> crud.comments.last.article => #<Article id: 1, title: "The CRUD", body: "...", …> Associated Models You can query through the association
  • 43. >> crud = Article.first => #<Article id: 1, title: "The CRUD", body: "...", …> >> crud.comments.count => 3 >> crud.comments => [#<Comment id: 1, article_id: 1, body: "First!", …>, #<Comment id: 2, article_id: 1, body: "Tard.", …>, #<Comment id: 3, article_id: 1, body: "Am not!", …>] >> crud.comments.last => #<Comment id: 3, article_id: 1, body: "Am not!", …> >> crud.comments.last.article => #<Article id: 1, title: "The CRUD", body: "...", …> Associated Models You can query through the association
  • 44. >> crud = Article.first => #<Article id: 1, title: "The CRUD", body: "...", …> >> crud.comments.count => 3 >> crud.comments => [#<Comment id: 1, article_id: 1, body: "First!", …>, #<Comment id: 2, article_id: 1, body: "Tard.", …>, #<Comment id: 3, article_id: 1, body: "Am not!", …>] >> crud.comments.last => #<Comment id: 3, article_id: 1, body: "Am not!", …> >> crud.comments.last.article => #<Article id: 1, title: "The CRUD", body: "...", …> Associated Models You can query through the association
  • 45. >> crud = Article.first => #<Article id: 1, title: "The CRUD", body: "...", …> >> crud.comments.count => 3 >> crud.comments => [#<Comment id: 1, article_id: 1, body: "First!", …>, #<Comment id: 2, article_id: 1, body: "Tard.", …>, #<Comment id: 3, article_id: 1, body: "Am not!", …>] >> crud.comments.last => #<Comment id: 3, article_id: 1, body: "Am not!", …> >> crud.comments.last.article => #<Article id: 1, title: "The CRUD", body: "...", …> Associated Models You can query through the association
  • 46. >> crud = Article.first => #<Article id: 1, title: "The CRUD", body: "...", …> >> crud.comments.count => 3 >> crud.comments => [#<Comment id: 1, article_id: 1, body: "First!", …>, #<Comment id: 2, article_id: 1, body: "Tard.", …>, #<Comment id: 3, article_id: 1, body: "Am not!", …>] >> crud.comments.last => #<Comment id: 3, article_id: 1, body: "Am not!", …> >> crud.comments.last.article => #<Article id: 1, title: "The CRUD", body: "...", …> Associated Models You can query through the association
  • 47. Adding to an Association There are multiple ways to add in new models
  • 48. >> a = Article.create!(:title => "Needs Comments") => #<Article id: 3, title: "Needs Comments", body: nil, …> >> a.comments => [] >> a.comments.create!(:body => "create!()") => #<Comment id: 6, article_id: 3, body: "create!()", …> >> a.comments << Comment.new(:body => "<<") => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] >> c = a.comments.build(:body => "build()") => #<Comment id: nil, article_id: 3, body: "build()", created_at: nil, updated_at: nil> >> c.save! => true >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] Adding to an Association There are multiple ways to add in new models
  • 49. >> a = Article.create!(:title => "Needs Comments") => #<Article id: 3, title: "Needs Comments", body: nil, …> >> a.comments => [] >> a.comments.create!(:body => "create!()") => #<Comment id: 6, article_id: 3, body: "create!()", …> >> a.comments << Comment.new(:body => "<<") => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] >> c = a.comments.build(:body => "build()") => #<Comment id: nil, article_id: 3, body: "build()", created_at: nil, updated_at: nil> >> c.save! => true >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] Adding to an Association There are multiple ways to add in new models
  • 50. >> a = Article.create!(:title => "Needs Comments") => #<Article id: 3, title: "Needs Comments", body: nil, …> >> a.comments => [] >> a.comments.create!(:body => "create!()") => #<Comment id: 6, article_id: 3, body: "create!()", …> >> a.comments << Comment.new(:body => "<<") => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] >> c = a.comments.build(:body => "build()") => #<Comment id: nil, article_id: 3, body: "build()", created_at: nil, updated_at: nil> >> c.save! => true >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] Adding to an Association There are multiple ways to add in new models
  • 51. >> a = Article.create!(:title => "Needs Comments") => #<Article id: 3, title: "Needs Comments", body: nil, …> >> a.comments => [] >> a.comments.create!(:body => "create!()") => #<Comment id: 6, article_id: 3, body: "create!()", …> >> a.comments << Comment.new(:body => "<<") => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] >> c = a.comments.build(:body => "build()") => #<Comment id: nil, article_id: 3, body: "build()", created_at: nil, updated_at: nil> >> c.save! => true >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] Adding to an Association There are multiple ways to add in new models
  • 52. Deleting Associated Models To delete associated models, find normally and call destroy()
  • 53. >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] >> c = a.comments.find(8) => #<Comment id: 8, article_id: 3, body: "build()", …> >> c.destroy if c => #<Comment id: 8, article_id: 3, body: "build()", …> >> a.comments(true) => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] Deleting Associated Models To delete associated models, find normally and call destroy()
  • 54. >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] >> c = a.comments.find(8) => #<Comment id: 8, article_id: 3, body: "build()", …> >> c.destroy if c => #<Comment id: 8, article_id: 3, body: "build()", …> >> a.comments(true) => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] Deleting Associated Models To delete associated models, find normally and call destroy()
  • 55. >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] >> c = a.comments.find(8) => #<Comment id: 8, article_id: 3, body: "build()", …> >> c.destroy if c => #<Comment id: 8, article_id: 3, body: "build()", …> >> a.comments(true) => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] Deleting Associated Models To delete associated models, find normally and call destroy()
  • 56. >> a.comments => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>, #<Comment id: 8, article_id: 3, body: "build()", …>] >> c = a.comments.find(8) => #<Comment id: 8, article_id: 3, body: "build()", …> >> c.destroy if c => #<Comment id: 8, article_id: 3, body: "build()", …> >> a.comments(true) => [#<Comment id: 6, article_id: 3, body: "create!()", …>, #<Comment id: 7, article_id: 3, body: "<<", …>] Deleting Associated Models To delete associated models, find normally and call destroy()
  • 57. Using Associations Correctly
  • 58. Using Associations Correctly You should very rarely need to refer to an ID
  • 59. Using Associations Correctly You should very rarely need to refer to an ID Let Rails worry about that for you
  • 60. Using Associations Correctly You should very rarely need to refer to an ID Let Rails worry about that for you It’s safer to scope as many queries as possible through the association
  • 61. Using Associations Correctly You should very rarely need to refer to an ID Let Rails worry about that for you It’s safer to scope as many queries as possible through the association There’s less chance to affect the wrong data
  • 62. Using Associations Correctly You should very rarely need to refer to an ID Let Rails worry about that for you It’s safer to scope as many queries as possible through the association There’s less chance to affect the wrong data It adds security against users trying to spoof ID’s
  • 63. One to One users id first_name last_name 1 James Gray 2 Dana Gray photos id user_id path 1 1 /images/james.png
  • 64. One to One A user has_one() photo
  • 65. class User < ActiveRecord::Base has_one :photo end class Photo < ActiveRecord::Base belongs_to :user end One to One A user has_one() photo
  • 66. Model Attributes Just assign a belongs_to()/has_one() to set it (or call build_photo()/create_photo())
  • 67. >> james = User.find_by_first_name("James") => #<User id: 1, first_name: "James", last_name: "Gray", …> >> james.photo = Photo.new(:path => "/images/james.png") => #<Photo id: 1, user_id: 1, path: "/images/james.png", …> Model Attributes Just assign a belongs_to()/has_one() to set it (or call build_photo()/create_photo())
  • 68. >> james = User.find_by_first_name("James") => #<User id: 1, first_name: "James", last_name: "Gray", …> >> james.photo = Photo.new(:path => "/images/james.png") => #<Photo id: 1, user_id: 1, path: "/images/james.png", …> Model Attributes Just assign a belongs_to()/has_one() to set it (or call build_photo()/create_photo())
  • 69. photos Many to Many id path 1 /images/mac.jpg taggings 2 /images/pc.bmp id photo_id tag_id 1 1 1 tags id name 2 1 2 1 computer 3 1 3 2 sexy 4 2 4 3 lickable 4 junk
  • 70. Many to Many Photos have many tags
  • 71. class Photo < ActiveRecord::Base has_many :taggings has_many :tags, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :photo belongs_to :tag end class Tag < ActiveRecord::Base has_many :taggings has_many :photos, :through => :taggings end Many to Many Photos have many tags
  • 72. class Photo < ActiveRecord::Base has_many :taggings has_many :tags, :through => :taggings end class Tagging < ActiveRecord::Base belongs_to :photo belongs_to :tag end class Tag < ActiveRecord::Base has_many :taggings has_many :photos, :through => :taggings end Many to Many Photos have many tags
  • 73. has_many :through The nested association is mostly managed by Rails for you
  • 74. >> mac = Photo.first => #<Photo id: 1, user_id: 1, path: "/images/mac.jpg", …> >> mac.taggings => [#<Tagging id: 1, photo_id: 1, tag_id: 1, …>, #<Tagging id: 2, photo_id: 1, tag_id: 2, …>, #<Tagging id: 3, photo_id: 1, tag_id: 3, …>] >> mac.tags => [#<Tag id: 1, name: "computer", …>, #<Tag id: 2, name: "sexy", …>, #<Tag id: 3, name: "lickable", …>] >> pc = Photo.last => #<Photo id: 2, user_id: nil, path: "/images/pc.bmp", …> >> comp = Tag.find_or_create_by_name("computer") => #<Tag id: 1, name: "computer", …> >> pc.taggings.create!(:tag => comp) => #<Tagging id: 5, photo_id: 2, tag_id: 1, …> has_many :through The nested association is mostly managed by Rails for you
  • 75. >> mac = Photo.first => #<Photo id: 1, user_id: 1, path: "/images/mac.jpg", …> >> mac.taggings => [#<Tagging id: 1, photo_id: 1, tag_id: 1, …>, #<Tagging id: 2, photo_id: 1, tag_id: 2, …>, #<Tagging id: 3, photo_id: 1, tag_id: 3, …>] >> mac.tags => [#<Tag id: 1, name: "computer", …>, #<Tag id: 2, name: "sexy", …>, #<Tag id: 3, name: "lickable", …>] >> pc = Photo.last => #<Photo id: 2, user_id: nil, path: "/images/pc.bmp", …> >> comp = Tag.find_or_create_by_name("computer") => #<Tag id: 1, name: "computer", …> >> pc.taggings.create!(:tag => comp) => #<Tagging id: 5, photo_id: 2, tag_id: 1, …> has_many :through The nested association is mostly managed by Rails for you
  • 76. >> mac = Photo.first => #<Photo id: 1, user_id: 1, path: "/images/mac.jpg", …> >> mac.taggings => [#<Tagging id: 1, photo_id: 1, tag_id: 1, …>, #<Tagging id: 2, photo_id: 1, tag_id: 2, …>, #<Tagging id: 3, photo_id: 1, tag_id: 3, …>] >> mac.tags => [#<Tag id: 1, name: "computer", …>, #<Tag id: 2, name: "sexy", …>, #<Tag id: 3, name: "lickable", …>] >> pc = Photo.last => #<Photo id: 2, user_id: nil, path: "/images/pc.bmp", …> >> comp = Tag.find_or_create_by_name("computer") => #<Tag id: 1, name: "computer", …> >> pc.taggings.create!(:tag => comp) => #<Tagging id: 5, photo_id: 2, tag_id: 1, …> has_many :through The nested association is mostly managed by Rails for you
  • 77. >> mac = Photo.first => #<Photo id: 1, user_id: 1, path: "/images/mac.jpg", …> >> mac.taggings => [#<Tagging id: 1, photo_id: 1, tag_id: 1, …>, #<Tagging id: 2, photo_id: 1, tag_id: 2, …>, #<Tagging id: 3, photo_id: 1, tag_id: 3, …>] >> mac.tags => [#<Tag id: 1, name: "computer", …>, #<Tag id: 2, name: "sexy", …>, #<Tag id: 3, name: "lickable", …>] >> pc = Photo.last => #<Photo id: 2, user_id: nil, path: "/images/pc.bmp", …> >> comp = Tag.find_or_create_by_name("computer") => #<Tag id: 1, name: "computer", …> >> pc.taggings.create!(:tag => comp) => #<Tagging id: 5, photo_id: 2, tag_id: 1, …> has_many :through The nested association is mostly managed by Rails for you
  • 78. Many to Many (Two Tables) followings users id follower_id followed_id id first_name last_name 1 1 4 1 James Gray 2 2 4 2 Dana Gray 3 3 1 3 Super Man 4 4 1 4 Bat Man 5 5 1 5 Spider Man
  • 79. Many to Many (Two Tables) Users have many followers
  • 80. class Following < ActiveRecord::Base belongs_to :follower, :class_name => "User", :foreign_key => :follower_id belongs_to :followed, :class_name => "User", :foreign_key => :followed_id end class User < ActiveRecord::Base has_many :other_followings, :class_name => "Following", :foreign_key => :followed_id has_many :followers, :through => :other_followings has_many :self_followings, :class_name => "Following", :foreign_key => :follower_id has_many :followed_by, :through => :self_followings, :source => :followed end Many to Many (Two Tables) Users have many followers
  • 81. class Following < ActiveRecord::Base belongs_to :follower, :class_name => "User", :foreign_key => :follower_id belongs_to :followed, :class_name => "User", :foreign_key => :followed_id end class User < ActiveRecord::Base has_many :other_followings, :class_name => "Following", :foreign_key => :followed_id has_many :followers, :through => :other_followings has_many :self_followings, :class_name => "Following", :foreign_key => :follower_id has_many :followed_by, :through => :self_followings, :source => :followed end Many to Many (Two Tables) Users have many followers
  • 82. class Following < ActiveRecord::Base belongs_to :follower, :class_name => "User", :foreign_key => :follower_id belongs_to :followed, :class_name => "User", :foreign_key => :followed_id end class User < ActiveRecord::Base has_many :other_followings, :class_name => "Following", :foreign_key => :followed_id has_many :followers, :through => :other_followings has_many :self_followings, :class_name => "Following", :foreign_key => :follower_id has_many :followed_by, :through => :self_followings, :source => :followed end Many to Many (Two Tables) Users have many followers
  • 83. class Following < ActiveRecord::Base belongs_to :follower, :class_name => "User", :foreign_key => :follower_id belongs_to :followed, :class_name => "User", :foreign_key => :followed_id end class User < ActiveRecord::Base has_many :other_followings, :class_name => "Following", :foreign_key => :followed_id has_many :followers, :through => :other_followings has_many :self_followings, :class_name => "Following", :foreign_key => :follower_id has_many :followed_by, :through => :self_followings, :source => :followed end Many to Many (Two Tables) Users have many followers
  • 84. Two-way Relationships Once you get the relationships right, Rails can still manage the messy details
  • 85. >> james = User.find_by_first_name("James") => #<User id: 1, first_name: "James", last_name: "Gray", …> >> james.followers => [#<User id: 3, first_name: "Super", last_name: "Man", …>, #<User id: 4, first_name: "Bat", last_name: "Man", …>, #<User id: 5, first_name: "Spider", last_name: "Man", …>] >> james.followed_by => [#<User id: 4, first_name: "Bat", last_name: "Man", …>] >> bat = User.find_by_first_name("Bat") => #<User id: 4, first_name: "Bat", last_name: "Man", …> >> bat.followers => [#<User id: 1, first_name: "James", last_name: "Gray", …>, #<User id: 2, first_name: "Dana", last_name: "Gray", …>] Two-way Relationships Once you get the relationships right, Rails can still manage the messy details
  • 86. >> james = User.find_by_first_name("James") => #<User id: 1, first_name: "James", last_name: "Gray", …> >> james.followers => [#<User id: 3, first_name: "Super", last_name: "Man", …>, #<User id: 4, first_name: "Bat", last_name: "Man", …>, #<User id: 5, first_name: "Spider", last_name: "Man", …>] >> james.followed_by => [#<User id: 4, first_name: "Bat", last_name: "Man", …>] >> bat = User.find_by_first_name("Bat") => #<User id: 4, first_name: "Bat", last_name: "Man", …> >> bat.followers => [#<User id: 1, first_name: "James", last_name: "Gray", …>, #<User id: 2, first_name: "Dana", last_name: "Gray", …>] Two-way Relationships Once you get the relationships right, Rails can still manage the messy details
  • 87. >> james = User.find_by_first_name("James") => #<User id: 1, first_name: "James", last_name: "Gray", …> >> james.followers => [#<User id: 3, first_name: "Super", last_name: "Man", …>, #<User id: 4, first_name: "Bat", last_name: "Man", …>, #<User id: 5, first_name: "Spider", last_name: "Man", …>] >> james.followed_by => [#<User id: 4, first_name: "Bat", last_name: "Man", …>] >> bat = User.find_by_first_name("Bat") => #<User id: 4, first_name: "Bat", last_name: "Man", …> >> bat.followers => [#<User id: 1, first_name: "James", last_name: "Gray", …>, #<User id: 2, first_name: "Dana", last_name: "Gray", …>] Two-way Relationships Once you get the relationships right, Rails can still manage the messy details
  • 88. Extras Rails associations have quite a few options
  • 89. Finder Options and Dependance
  • 90. Finder Options and Dependance Set :conditions, :order, etc. on associations
  • 91. Finder Options and Dependance Set :conditions, :order, etc. on associations Example: :order => “created_at DESC”
  • 92. Finder Options and Dependance Set :conditions, :order, etc. on associations Example: :order => “created_at DESC” Specify what happens to associations with destroy()
  • 93. Finder Options and Dependance Set :conditions, :order, etc. on associations Example: :order => “created_at DESC” Specify what happens to associations with destroy() :dependent => :destroy forwards destroy()
  • 94. Finder Options and Dependance Set :conditions, :order, etc. on associations Example: :order => “created_at DESC” Specify what happens to associations with destroy() :dependent => :destroy forwards destroy() :dependent => :nullify breaks the link
  • 95. Polymorphic Associations
  • 96. Polymorphic Associations Rails has a special type of “Polymorphic Association”
  • 97. Polymorphic Associations Rails has a special type of “Polymorphic Association” Models are linked with a type and an ID
  • 98. Polymorphic Associations Rails has a special type of “Polymorphic Association” Models are linked with a type and an ID This makes it possible to link one model to multiple different kinds of other models
  • 99. Polymorphic Associations Rails has a special type of “Polymorphic Association” Models are linked with a type and an ID This makes it possible to link one model to multiple different kinds of other models For example, you might use a Comment model to allows users to comment on multiple things (products and reviews for example)
  • 100. Questions?
  • 101. Fleshing out the Data Layer Lab Your book has instructions on how to add new models and associate them with existing tables