Ruby on Rails/ActiveRecord/Associations

Introduction
Associations are methods to connect 2 models. Operations on objects become quite simple. The association describes the role of relations that models are having with each other. ActiveRecord associations can be used to describe one-to-one (1:1), one-to-many (1:n) and many-to-many (n:m) relationships between models. There are several types of associations


 * belongs_to and
 * has_one form a one-to-one relationship
 * has_one :through is a different way to create a one-to-one relationship


 * has_many and
 * belongs_to form a one-to-many relation


 * has_and_belongs_to_many or an alternative way
 * has_many :through to create a many-to-many relationship

For all following examples, we assume the following 4 models:

Also check out the ER-diagram for the models below:



belongs_to
The belongs_to association sets up an one-to-one (1:1) or one-to-many (1:n) relationship to an other model.

In our example, one Rating belongs to exactly one Product, so we need to set up a belongs_to association.

The product stores an id for a rating, both of them have a one-to-one Relationship. Meaning: One product belongs to one category and one product belongs to one rating.

has_one
The has_one association is a one-to-one relation too. It declares that each instance of a product from the productmodel possesses only one rating_id.

Since the rating and the product form a one-to-one relationship, it is up to us where we put the reference. Because we have put the reference (the rating_id) into the product (see belongs_to :rating into the product model), the association for the rating has to be has_one:product. Has_one and belongs_to always go together to form a relationship.

has_many
This is a one-to-many connection to an other model. In this case, one category has many products. Pay attention to the spelling, if you use has_many. The model that you want to reference needs to be written in plural.

The category and the product are forming a one-to-many relationship. Since a category has many products we put the has_many association inside the category. Note that also the product needs to contain a reference to the category. One product belongs to exactly one category, therefore we put belongs_to :category inside the product model.

has_and_belongs_to_many
Also known as : HABTM.

<tt>Has_and_belongs_to_many</tt> is the most complex association. You need to keep some things in mind: Because of the way relational databases work, you can not set up a direct relationship. You need to create a joining table. This is easily done with migrations. If we want to create a HABTM association for our product and tag, the association for the joining table might look like following:

Because we do not need a primary key inside the join table, we use <tt>:id => false</tt> to prevent the automatic creation of a primary key column. The naming of the table needs to be in alphabetical order. "P" is before "T" in the alphabet so the tablename has to be products_tags (note: plural).

has_many :through
This association is an other way to form a many-to-many relation. Consider the following ER-Diagramm to show the relationship.



Instead of using a join table we use another model for the relationship. If we want to find out which supplier is responsible for a specific category we need the product to link the models together. This way we can store additional data inside a real model that also acts as a joining model. Whenever you need to store data that additionally belongs to association (e.g. the date of the creation) you might want to use this type of association.

has_one :through
As with <tt>has_many :through</tt>, <tt>the has_one :through</tt> association uses an "extra" model to form a relation.

Consider this visual relationship:



Note: This example assumes that the membership inside a group is exclusive for each user.