Last week we looked at getting started with Active Record in Ruby on Rails.

Rails’ implementation of the Active Record pattern is a big reason why the framework is approachable for beginners, yet powerful for professionals.

The Active Record pattern encapsulates database access and business logic as a single object. An important part of this is how objects are associated to other objects and subsequently mapped in the database.

In today’s tutorial we will be looking at Active Record Associations in Ruby on Rails.

Defining Associations

If you’re reading this tutorial I’m going to assume you are already familiar with the common relationship patterns of relational databases.

The first thing to understand is how to define a relationship on an Active Record model. Here’s how you do it:

class Article < ActiveRecord::base  
has_many :comments  
end  

If you are new to programming, the above code has probably went straight over your head, and if you are coming to Ruby from another language you’re probably thinking, “what on earth is going on here?”

To define an association in an Active Record model you use the Rails DSL.

In the example above, has_many is simply a method that is invoked within the context of the current model.

The method accepts an argument (in this case :comments). This is a symbol (What are Symbols in Ruby?).

When the object is loaded, Ruby will invoke the has_many method and create the association automatically on the object.

This syntax seems kinda weird when you first start looking at Rails, it took me a while to get my head around, but it’s really just calling a method on the object.

Now any instance of Article will have a comments method that will hold the related comments for that record:

article = Article.find(123)  
article.comments  

Working with Has Many associations

In the section above we defined a has_many relationship on the Article model that relates to the Comment model:

class Article < ActiveRecord::base  
has_many :comments  
end  

The inverse of this relationship can be defined on the Comment model like this:

class Comment < ActiveRecord::base  
belongs_to :article  
end  

This allows you to access the Article from the Comment object:

comment = Comment::find(456)  
comment.article  

To add a Comment to an Article we can simply use regular Ruby code:

article.comments << Comment.create(body: "Very interesting!")  

Working with One to One associations

A relationship where an object is associated to a single other object can be defined using the has_one and belongs_to methods:

class User < ActiveRecord::Base  
has_one :avatar  
end

class Avatar < ActiveRecord::Base  
belongs_to :user  
end  

Once again, now that you’ve defined the relationship you will be able to access it through the associated instance method:

user = User.first  
user.avatar.src  
=> "profile-234.jpg"  

Working with Many to Many associations

Finally the most tricky relationship to get right is where many objects are related to many other objects. To do this we need an intermediate join table that sits in between the association.

This kind of relationship can be defined like this:

class Article < ActiveRecord::Base  
has_many :taggings  
has_many :tags, through :taggings  
end  

As you can see, we are specifying that this relationship should go through the :taggings association. So next we need to define that model:

class Tagging < ActiveRecord::Base  
belongs_to :article  
belongs_to :tag  
end  

Finally we can define the inverse of the relationship:

class Tag < ActiveRecord::Base  
has_many :taggings  
has_many :articles, through :taggings  
end  

You can now access the tags through the tags method:

article = Article.first  
article.tags  

Conclusion

Understanding the associations between models is a big step towards being able to build web applications.

One of the first steps when building a web application is usually gathering the specifications from the given requirements.

Being able to visualise, and then implement how the important entities of the applications are associated is an integral skill of this step.

Rails makes associating your models very easy. Your models will automatically gain the functionality of the defined association and they will automatically deal with translating from a relational database into a object context.