A record in a data model often has a relationship to one or more records in another model. For example, a web application may have a Movie data model and a Review data model. Since a movie can have several reviews, we say that a review belongs to a review.
Below are the different types of relationships records with one model can have with records in a different model:
In addition to Chapter 9 in the text, here's a nice summary sheet for model relationships.
Implementing a model relationship in Rails involves the following steps:
For Rails applications, the foreign key is only applied to models that have the belongs_to relationship. For example, if a Review belongs to a Movie, then it's the Review model that has the foreign key. Setting up the relationship is easiest if the Rails naming convention is followed for the foreign key. For example, a foreign key in the Review model that references a Movie record should have the name movie_id with a type of integer.
This join table connects the records from one model to records in another model. The join table consists of pairs of foreign keys and should be named using the names of the joined tables separated by an underscore (e.g. recipes_ingredients). For example, recipes can have many ingredients and ingredients can be in many recipes. If the models are called Recipe and Ingredient, each record in the join table (called recipes_ingredients) consists of the fields recipe_id and ingredient_id. Pages 162 to 165 go through the steps of creating a join table for this relationship.
Explicitly stating the model relationships in the class files allows for easy object-oriented references. Both directions of the relationship should be stated in the files. For example, the movie.rb file should have the following statement:
has_many :reviews
The review.rb file should have this statement:
belongs_to :movie
Note the use of the singular or plural when referring to a data model.
It's possible to update the routing rules so that dependent relationships are explicitly depicted in the URL request. For example, a review belongs to (depends on) a movie. This relationships can be represented in a URL. For example, if the movie has id of 5 and the review has an id of 8, then this nested URL shows the relationship when requesting review 8:
http://localhost:3000/movies/5/reviews/8
This URL shows that review 8 belongs to movie 5. You can enable this routing scheme by altering the routes.rb file:
map.resources :students, has_many => [ :reviews ]
You should also delete the line with map.resources :reviews.
If the model class files explicitly state the relationships, you can reference model objects from a related object. Here are examples with Movie and Review models (assuming m is a Movie object and r is a Review object):
For views, you might want to allow users to choose the object of the belongs_to relationship when creating a new record. For example, a user might want to write a new review and select the movie from a menu. Here's the needed code for the view:
<%= f.select :movie_id, Movie.find(:all).collect { |m| [m.title, m.id] }