Active Record Associations For Dummies

Jonathan Zavala
6 min readMar 19, 2021

Active Record Associations

What are active record associations? Why do we use them? How do we use them? I will be answering all three of these questions in this blog and hopefully answering any other question you would have on this topic. Let’s dive right in.

What Is Active Record Association?

An association in Rails or Sinatra is a connection between two Active Record models. The reason we use associations between models is because it makes operations that are used often easier and simpler to code. Without associations this is what our models would look like:

with our models like this to create a new dog and assign it to an owner our code would have to look something like : @dog = Dog.create(name: “Fido”, owner_id: @owner.id). Now if our models had active record associations in them they would look like this:

Now that we are using active record associations we can now create a new dog and assign him to a new owner with this line of code: @dog = @owner.dogs.create(name: “Fido”). Now that is much better and that has to do with the methods that active record associations gives to us, but I’ll touch on that later. For now I need to show y’all the different associations, creating their tables and migrations!!

Association Types

There are six different types of associations supported by Rails, but for this blog we’re only going to focus on three of them. The methods are: “belongs_to”, “has_many” and “has_many :through”.

Belongs_to

The belongs_to association sets up a connection with another model that is a “Parent” model, therefore the belongs_to model is considered the child model and here is what I mean by that. Assume you have an owner model and a dog model, the dog is assigned to ONE owner therefore he belongs to the owner. The same way a child belongs_to a parent. Here is an example of the model:

The migration you would make for this would look something like:

This is only one side of the connection for this association. We must make it a bidirectional association.

Has_many

The has_many association means that the instance of the model can have many instances of another model. Let’s continue with the example from before except now we’re viewing it from the owner’s side. As an owner you can have more than one dog if you want correct? Well this is exactly what this association means, and owner can have many dogs. This is what the model will look like:

With the migration looking like this:

Has_many :through

Has many_through is a many-to-many connection like has_many except it has twist to it. The declaring model of the has_many :through association is able to match with other instances from other models through a third model. For example assume you’re an artist who makes songs well these songs have genres. The songs belongs_to the genre and belongs_to the artist, with the songs model acting as a join-table-model the artist is able to match with the genres. So the artist able to have many different genres through the songs and vice versa. Here’s an example of the models:

and their migrations would look like this:

Now we’ll talk about the methods that these Active Record Associations give us and how to use them to your advantage!

Active Record Association Methods

Each association adds a number of methods to the class which specialized according to the association or options hash and the collection. They are used for retrieval and querying. There is a long list of methods added for these associations I will only be covering a few in detail and with examples just for the sake of time. I’ll link the documentation here.

With belongs_ to the methods will be added for retrieval and query for a single associated object, for which this object holds an id, association is a placeholder for the symbol passed as the name argument, so belongs_to :artist would add among others artist.nil?.

create_association(attributes = {})

Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).

Example : Let’s say you have a Song class that declares belongs_to :artist. With this line of code : create_artist(attributes={}) you will create a new artist, save the artist and associate it with the post. The old code would have looked like this: song.artist = Artist.new; song.artist.save; song.artist. I’d say I prefer the shorter version.

With has_many and has_many :through the collection is the place holder for the symbol passed as the name argument. The collection returns a relation with all associated objects! Whatever the objects the class is associated we can find out information about them!

Some examples of this are:

collection.clear

Removes every object from the collection. This destroys the associated objects if they are associated with dependent: :destroy, deletes them directly from the database if dependent: :delete_all, otherwise sets their foreign keys to NULL. If the :through option is true no destroy callbacks are invoked on the join models. Join models are directly deleted.

collection.empty?

Returns true if there are no associated objects.

collection.size

Returns the number of associated objects.

collection.find(…)

Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.

collection.exists?(…)

Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::FinderMethods#exists?.

They are very handy and allow us to write code faster and easier.

Conclusion

Active Record Association makes it so much easier to express relationships in our applications and gives up nice methods to query and locate things in our code. It allows us to focus on the harder code and not have to deal with the repetition in our code. I really hope this blog helped with what you were looking for, I know I learned a lot just writing it and I hope putting it in my own words and wording helped you better understand it. We’re all here to learn from each other! Please if you have any feed back let me know I’m always willing to learn!

--

--