Sitemap

Making a Followers Feature with Ruby on Rails and Active Record

4 min readMar 22, 2017

For a project I decided to make my own version of Instagram. I learned a lot while building this project but if I had to pick a a feature from which I learned the most, I would definitely have to say it was the Followers feature.

There are many ways of building this feature, I decided to use one join table. So we would have users joining users. At a glance this feature does not seem very difficult. To be honest, the difficult part was understanding how to do this with active record macros. So if your currently struggling with this, YOU ARE IN THE RIGHT PLACE!!!

Lets start with the join table, we will call it “Follows”. The schema should look like this:

Join Table

Alright, so as you can see one column contains the user_id, this is the id of the user has made the request to follow someone. The second column pertains to the user who the request has been made to. Alright lets now go set up the model for this join table.

These are going to be our active records macros for our Follow model

Press enter or click to view image in full size
Join Model

At a glance this might look a little confusing, but don’t worry I’ll walk you through it!

So as you can see our join model belongs to two types of users, a “follower” and a “following”. These are custom names that we have given the model to identify different users. Notice how the foreign_keys of each individual macro is equivalent to a column in the database; this is the column in the database it will look at when this macro is invoked. The reason we have to do this is because we are using a custom name(“follower” and “following”) so we have to let it know where in the database it’ll be looking.

Ok now lets handle the User model, this is where the MAGIC happens. Your User model should look like this:

Press enter or click to view image in full size

As you can see there is a lot going on in here, lets break it down. First off, we have to say “has_many :follows” since “follows” is the join table and has the users foreign keys. You might be wondering what we are doing in our second line of code. Well, active record does not allow us to set “foreign_key” and do a “through” in the same macro, therefore we have to break it down into two macros.

Press enter or click to view image in full size

Now lets explain further what is going on in the second line of code. “follower_relationships” is actually a virtual table; pretty much its a fake table created by active record. Next we give it a foreign key, this will allow active to know which column in the database it will look for the ID of the instance of the User model that is invoking the method. We do this because to get your followers we need to see where your ID is in the following_id column. Lastly we give it a class name; since this is a virtual table and does not exist, so we have to tell active record which table it is going to be getting the information from, here we tell it “Follow”.

Press enter or click to view image in full size

Next we have so say have many “followers”. This is the method call that each instance of the User class will be using to get its followers. Now we can do a through on “follower_relationships”, with a source of “follower”. Remember that custom macro we did in the Follow model, well this is where we use it! The source key tell active record where to look at when accessing “follower_relationships”, but remember “follower_relationships” is a custom version of the Follow model.

Press enter or click to view image in full size
This is part of the Follow model

Therefore when it access the “follower_relationships” model it knows to look at “belongs_to :follower”. The “belongs_to :follower” has a foreign key of “user_id”, which means it brings out of the database all the rows in user_id column where the “following_id” is the ID of the instance calling the followers method!

The following macro is literally the opposite of the followers; it simply looks at the other column in the database.

This whole process can obviously be done without active record, but this feature really focusses in making your code dry and abstract. Also it was great practice!

--

--

No responses yet