Polymorphic Relationship in Strapi.js

Strapi is a wonderful tool for creating a quick API. Do you want to create an app concept and be done in three days with the backend, strap is your tool.

Strapi does have some limitation as of today 8/11/21. One of these is creating polymorphic relationships.

A polymorphic relationship is a class/model relationship where you can associate more than one model to a single class. E.g a User can have a comment on a video, a post or a picture.On one table you can have all comments that link to videos, posts and pictures.
In this article I will show you a convenient way to create this relationship, and since there is no native functionality there will be a little bit of redundancy.

Here is my opinionated work-around the lack of polymorphic relationships in the tool:

  1. Create the relationship on the main model
  2. Create a polymorphic model with the polymorphic fields as columns
  3. Create Logic to work around the polymorphic relationship
  4. Understand the cost of redundancy in your data

Create the relationship on the main model

In my use case a User can have a comment on a video, post and picture. I will be adding this data twice. Once as a comment, and the second time as a relationship.

In this case there will be a comment table that looks like this:

id comment user_id
1 1st Comment 1

Create a polymorphic model with the polymorphic fields as columns

Create a table called commentable. In this table we will link comments from the comment table to videos, photos and posts:

id comment_id post_id picture_id video_id
1 1 1 NULL NULL
2 2 NULL 1 NULL

You can also add user_id to this table as a redundancy. Or another way to model the table will be to add the comment and user_id directly to this table. It’s up to you.

In this use case, you can grab comments with:

  1. Post hasMany Comments relationship
  2. Video hasMany Comments relationship
  3. Picture hasMany Comment relationship
  4. User hasMany Comment relationship

Create Logic to work around the polymorphic relationship

For this, you will need to have a logic in your code either through the hasMany relationships for the main models (post, videos, pictures) or if you’re grabbing all user comments you can load the relationship based on the column e.g if commentable->post_id != null this comment belongs to a post.

Understand the cost of redundancy in your data

In a smaller bootstrapped need to have an MVP product in 2 weeks, or we have less than 120k users posting videos and pictures on the platform redundancy like this is not a big deal.  It lets you get a product to market quickly. Each null column adds an extra bit to the row in this case 2 extra bits for 2 null columns.

Longer term, you might need to make  data storage decisions that streamline every bit of data put in the DB. You might need to rewrite & streamline your code when you get to that point. 

Hopefully strapi accepts a polymorphic relationship soon.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top