54 Through Associations Referring back to Figure 511 there are direct

54 through associations referring back to figure 511

This preview shows page 191 - 193 out of 517 pages.

5.4 Through-Associations Referring back to Figure 5.11 , there are direct associations between Moviegoers and Reviews as well as between Movies and Reviews. But since any given Review is associated with both a Moviegoer and a Movie, we could say that there’s an indirect association between Moviegoers and Movies. For example, we might ask “What are all the movies Alice has reviewed?” or “Which moviegoers have reviewed Inception ?” Indeed, line 14 in Figure 5.13 essentially answers the second question. 1 # in moviegoer.rb: 2 class Moviegoer 3 has_many :reviews 4 has_many :movies, :through => :reviews 5 # ...other moviegoer model code 6 end 7 alice = Moviegoer.find_by_name(’Alice’) 8 alice_movies = alice.movies 9 # MAY work, but a bad idea - see caption: 10 alice.movies << Movie.find_by_name(’Inception’) # Don’t do this! Figure 5.17: Using through-associations in Rails. As before, the object returned by alice.movies in line 8 quacks like a collection. Note, however, that since the association between a Movie and a Moviegoer occurs through a Review belonging to both, the syntax in lines 9 and 10 will cause a Review object to be created to “link” the association, and by default all its attributes will be nil. This is almost certainly not what you want, and if you have validations on the Review object (for example, the number of potatoes must be an integer), the newly-created Review object will fail validation and cause the entire operation to abort. This kind of indirect association is so common that Rails and other frameworks provide an abstraction to simplify its use. It’s sometimes called a through-association , since Moviegoers are related to Movies through their reviews and vice versa. Figure 5.17 shows how to use the :through option to Rails’ has_many to represent this indirect association. You can similarly add has_many :moviegoers, :through=>:reviews to the Movie model, and write movie.moviegoers to ask which moviegoers are associated with (wrote reviews for) a given movie. How is a through-association “traversed” in the database? Referring again to Figure 5.12 , finding all the movies reviewed by Alice first requires forming the Cartesian product of the three tables ( movies , reviews , moviegoers ), resulting in a table that conceptually has 27 rows and 9 columns in our example. From this table we then select those rows for which the movie’s ID matches the review’s movie_id and the moviegoer’s ID matches the review’s moviegoer_id . Extending the explanation of Section 5.3 , the SQL query might look like this: 1 SELECT movies.* 2 FROM movies JOIN reviews ON movies.id = reviews.movie_id
Image of page 191
3 JOIN moviegoers ON moviegoers.id = reviews.moviegoer_id 4 WHERE moviegoers.id = 1; For efficiency, the intermediate Cartesian product table is usually not materialized, that is, not explicitly constructed by the database. Indeed, Rails 3 has a sophisticated relational algebra engine that constructs and performs optimized SQL join queries for traversing associations.
Image of page 192
Image of page 193

You've reached the end of your free preview.

Want to read all 517 pages?

  • Spring '19
  • Dr.Marcos

What students are saying

  • Left Quote Icon

    As a current student on this bumpy collegiate pathway, I stumbled upon Course Hero, where I can find study resources for nearly all my courses, get online help from tutors 24/7, and even share my old projects, papers, and lecture notes with other students.

    Student Picture

    Kiran Temple University Fox School of Business ‘17, Course Hero Intern

  • Left Quote Icon

    I cannot even describe how much Course Hero helped me this summer. It’s truly become something I can always rely on and help me. In the end, I was not only able to survive summer classes, but I was able to thrive thanks to Course Hero.

    Student Picture

    Dana University of Pennsylvania ‘17, Course Hero Intern

  • Left Quote Icon

    The ability to access any university’s resources through Course Hero proved invaluable in my case. I was behind on Tulane coursework and actually used UCLA’s materials to help me move forward and get everything together on time.

    Student Picture

    Jill Tulane University ‘16, Course Hero Intern

Stuck? We have tutors online 24/7 who can help you get unstuck.
A+ icon
Ask Expert Tutors You can ask You can ask You can ask (will expire )
Answers in as fast as 15 minutes
A+ icon
Ask Expert Tutors