feat: new post, clean up old placeholders
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
SauravDhakal
2026-04-01 21:55:48 +05:45
parent 2007e1f7b5
commit caca000c7f
3 changed files with 105 additions and 37 deletions

View File

@@ -1,11 +0,0 @@
---
title: "Sample Note"
date: 2025-08-20
# summary: "This is a sample note to demonstrate the notes section"
tags: ["example"]
draft: false
---
This is a sample note. Notes are meant to be short, quick thoughts or TILs (Today I Learned).
Delete this file and add your own notes here!

View File

@@ -1,26 +0,0 @@
---
title: "The Art of the Digital Garden"
date: 2026-04-01T08:55:00+05:45
draft: false
tags: ["philosophy", "gruvbox", "hugo"]
description: "Exploring the concept of a digital garden and how a refined Gruvbox theme enhances the experience."
---
Welcome to my digital garden. This is a place where I share my thoughts, projects, and lessons learned along the way. Unlike a traditional blog, a digital garden is always growing and evolving.
### Why Gruvbox?
Gruvbox is more than just a color scheme; it's a philosophy of contrast and harmony. By using the "Hard" contrast variant, we achieve a focus that is both easy on the eyes and aesthetically pleasing.
```javascript
const theme = "Gruvbox Dark Hard";
console.log(`Current theme: ${theme}`);
```
### The Beauty of Hugo
Hugo allows for lightning-fast build times and complete control over the structure of our content. Paired with a minimal theme like PaperMod, it provides the perfect canvas for technical writing.
> "A garden is never finished."
I hope you enjoy exploring these notes and posts as much as I enjoy writing them.

View File

@@ -0,0 +1,105 @@
---
title: "The Likes Table Problem: Why We Went Polymorphic."
date: 2026-04-01T21:50:00+05:45
draft: false
tags: ["architecture", "backend", "PSQL"]
description: "Concept of polymorphic table in an SQL database"
---
A few days ago, I was working on adding a **Community** section to an application. The idea was simple, users should be able to:
- Create posts
- Leave comments
- Like posts
- Like comments
We also had a separate News section. The new requirement was users should be able to like news articles as well.
Building model for `posts` and `comments` was pretty straight forward. The real challenge was to model the`likes`table.
## The Problem: How Do We Store Likes?
Were using PostgreSQL, so enforcing relationships with foreign keys is easy and clean.
If only **one** thing could be liked (say, News), the schema would be simple, we would have a `news_like` table which could look something like this:
| user_id | news_id | timestamp |
| --- | --- | --- |
| (foreign key) | (foreign key) | 1775059642 |
But we didnt have one entity. We had three. `posts`, `comments` and `news`.
We had to decide:
> Do we create three separate like tables? Or do we design one flexible solution?
## Option 1: Three Separate Tables
We could create three tables: `post_likes` , `comment_likes` and `news_likes` . Each table would have proper foreign key relationships. This approach would be a clean relational way of doing things. It:
- Keeps strong relational integrity
- Makes joins easy
- Keeps structure explicit
This is the most “pure relational” approach. But it felt repetitive. The schema grows horizontally.
And if tomorrow we add something else that can be liked, wed need yet another table.
It works, but it doesnt scale elegantly.
## Option 2: A Polymorphic Table (What We Chose)
Instead of multiple tables, we created a **single polymorphic likes table**.
### What is a Polymorphic Table?
A polymorphic table can reference multiple types of resources using a shared structure.
We designed our `likes` table to look something like this:
| user_id | resource_id | resource_type | timestamp |
| --- | --- | --- | --- |
| (foreign key) | (uuid) | (POST / COMMENT / NEWS) | |
Heres how it works:
- `user_id`: who liked, foreign key to `users` table.
- `resource_id` : the UUID of the item, just the uuid, no foreign key relation.
- `resource_type` : what type of item it is
- `timestamp` : timestamp
Instead of a strict foreign key to one table, we store:
- The ID
- The type of resource
Together, they uniquely identify what was liked.
With this approach, we had one clean and centralized table to store all kinds of likes. Its much easier to expand and flexible. Since “like” is a feature common to many parts of the system, this design keeps it generic and reusable.
But it does has a major downside. We lose direct foreign key enforcement on `resource_id`. Because PostgreSQL cant enforce a foreign key that dynamically points to multiple tables, referential integrity must be handled at the application level. We cannot write a simple join query to join from `comments` table or `posts` table.
For example, to fetch likes for a resource:
```tsx
SELECT COUNT(*)
FROM likes
WHERE resource_id = 'some-uuid'
AND resource_type = 'POST';
```
Now, if we need resource details plus likes, we may need separate queries or application-side logic.
For our use case though, that trade-off was acceptable. We dont perform heavy cross-entity joins on likes, so the downside was minimal.
## Why This Design Felt Right
The key insight was this:
> “Like” is not tightly coupled to Posts, Comments, or News. Its a behavior shared across resources.
>
By modeling it polymorphically, we treated “like” as a reusable system capability rather than a feature embedded in each entity.
And as our application grows, this decision will likely save us refactoring time.