DEV Community

Cover image for Rails: Self Referential Tables
Hsabes
Hsabes

Posted on

Rails: Self Referential Tables

For Sunday Night Football we crack open some cold ones with the boys, our friends. In other words, we're interacting with our friends. Virtually every social media application that has ever existed has some form of interaction between a user and their friends. You can message them, play games with them, tag them in posts, or add new friends... but what's actually happening on the back end? From a rails stand point, you can use Self Referrential Tables.

What are self referrential tables?

Take my previous Sunday Night Football example; we're interacting with friends right? But the word "friend" is a word we use to explain the relationship between two people. This is the basis of self referrential tables. A user has_many friends, but in technical terms, a user has_many other users. Self referrential tables are very confusing at first, so I'll give you some examples on how this data dance looks on the backend.

Models, serializers, and controllers... oh my!

For a self referrential table, we need two models (assuming a social media application for this example): The users, and the relationship: friends. Through this friends table you'll be able to connect users different ways. In this example we'll be looking at a following system. Take a look at this User.rb model from a recent project of mine:

user model

User.rb has_many catpanions, that's the name of the self referrential table connecting users. So what's this has_many :friends, through: :catpanions business? Well, let's now take a look at the Catpanions.rb model:

catpanion model

So a catpanion belongs_to a user, but also belongs_to a friend. We haven't made a friend model, so what's going on here? We've essentially told Ruby that there's other instances called friends that are really just instances of the User class. Now we need our foreign_keys.

catpanion serializer

These IDs are accessible because we declared our relationships when creating the resources:

catpanions create table

With all this set up, in order to create a friendship between two users you'll have to create the route in the controller handling the self referrential table.

route

When we fetch this route, we're telling the engine to first see if the user we're trying to add already exists in our friendships. If so, throw an error. If not, you have a new friend! The params used for the create should be the user_id and the friend_id. If you create a route that shows all the friendships, it should look something like this:

postman

Keep in mind, the user_id is the current user, and the friend_id is the person that they have followed. For the final touches, we want a way to access the people we've followed, right? In your user serializer, add the attribute :friends:

user serializer

Now if we take a look at a specific user, our data will reflect their friendships with the users they have followed:

user json

This kind of data can be extremely powerful when establishing some form of connection between users. If you're feeling a little overwhelmed don't worry, I had to play around with this concept for days to feel comfortable enough to use it in a project!

Top comments (1)

Collapse
 
bakivernes profile image
Vernes Pendić

The problem I have is that I cannot access the friends from the user that is the friend_id in the catpanions table. Only the other way around.