cult3

Understanding Active Record Associations

Oct 21, 2015

Table of contents:

  1. Defining Associations
  2. Working with Has Many associations
  3. Working with One to One associations
  4. Working with Many to Many associations
  5. Conclusion

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.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.