ActiveRecord Associations

Rex Ye
4 min readDec 19, 2019

Today I am going to talk about what really is happening behind ActiveRecord’s ‘magic’ on associations between models. Active Record is very powerful, but it is also very important to understand its structure and logic.

There are several types of associations, for instance:

  1. One-to-One
  2. One-to-Many
  3. Many-to-Many

For the purpose of this blog, we will be focusing on the many-to-many relation. We will be using a domain that consists of passengers, flights and tickets. One passenger can have many flights, and one flight can have many passengers. They are associated with one another by booking a flight ticket. Here’s the domain model:

Let’s build our models and have them inherited from ActiveRecord, then we will dive into what’s behind the scene of the ActiveRecord ‘magic’ on associations.

First let’s look at the joiner table, or the Ticket model that connects a passenger and a flight.

flight_id and passenger_id here will be the foreign keys

Thanks to the ActiveRecord inheritance, following actions can be performed:

Now let’s remove the inheritance from ActiveRecord, comment out “belongs_to :flight” and write our own implementations inside the Ticket class.

Iterating through Flight instances, and match flight.id with self.flight_id(self = ticket instance)

Now, run this in your console:

t1 = Ticket.new(passenger_id:5, flight_id:7)

The above method will return:

t1 is a Ticket instance we created.

Now, let’s build out our equivalent to Active Record’s “belongs_to :passenger”:

removed inheritance from ActiveRecord

Try creating a new association to a ticket, just like below:

Returns the passenger object that this ticket belongs to

Now, before we venture out to creating our own has_many methods, let’s look at the standard Active Record’s “has_many:” :

From the above lines of code, we can see that one passenger can have many tickets, and one passenger can be associated or have many flights through booking tickets. With these two lines of code written, we now will be able to execute the following:

How are we able to call tickets and flights on a Passenger instance with only two lines of code implemented?

Let’s look at the implementation behind the has_many:

Inside the Passenger class, we are going to remove the inheritance from ActiveRecord and try to accomplish the same tasks by defining instance methods:

Implementation of ActiveRecord has_many association

Now, check the associations in the console:

Array of ticket instances is being returned.

We’ve defined a class method “tickets” inside the Passenger class, which iterates through the Ticket class’s instances to find the ones that have the same passenger_id as self.id (here self will be a passenger instance). This method will return an array of ticket instances that are associated with this Passenger object, which is equivalent as ActiveRecord ‘s has_many: tickets.

Now, let’s look at the has_many through association. We will define another instance method inside the Passenger class:

We obtain the tickets instances by calling the instance method named tickets that we have defined earlier.

In order to obtain all the flights that are associated with a given passenger, we will first obtain the tickets that belong to this passenger, and then we transform that into an array of flight instances. After implementing this method, we will still be able to execute the following without inheriting from ActiveRecord:

returns array of flights associated with p1

We were able to transform the array of ticket instances into an array of flight instances because inside the Ticket class, where we have already implemented two instance methods:

With these two methods defined, Ticket object will have access to both its Passenger instance and Flight instance.

ActiveRecord ‘magic’ is very useful, but it is also essential to understand what is really happening behind the scene for a better command of the framework. In order to test out the implementations, I built it out myself — feel free to check out my GitHub repo here.

https://github.com/rexy91/ActiveRecord-Associations

Happy Coding!!!

--

--