Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anouarabsslm's avatar

Polymorphic trick to store comments

Hi guys , I'm going to share with you a trick that have saved me lot of work and avoid me to use more table with my DB . Lets start with the problem that I was trying to solve using Eloquent Polymorphic Relations. Lets say we have a topic which could have many posts, and users will be able to leave comments about the topic itself and also about the posts within this topic. I think this is a good situation to go with single table that store comments for both tables 'topics' and 'posts' , but my issue was how I can determine which user made this comment and where( commented on topic or in post). so to solve this issue here is my solution:

First let me share with you the DB schema for this example :

users
    id - integer
    username- string
    email -string
    password -string

topics
    id - integer
    title- string

posts
    id - integer
    body- text

Since I want to know which user made the comment I have to set relationship between users table and comments table like so:

comments
    id - integer
    body- text
   user_id-integer
    commentable_id - integer
    comment_type - string

Now you have an idea about DB structure, lets create our models for thus guys:

User Model

<?php

class User extends Eloquent{

    /**
     * @var string Table
     */
    protected $table = 'users';
} 

Comment Model

<?php

class Comment extends Eloquent{

    /**
     * @var string Table
     */
    protected $table = 'comments';

    public function commentable()
    {
        return $this->morphTo();
    }

    public function user()
    {
        return $this->belongsTo('User');
    }
} 

Topic Model

<?php

class Topic extends Eloquent{

    /**
     * @var string Table
     */
    protected $table = 'topics';

    public function comments()
    {
        return $this->morphMany('Comment', 'commentable');
    }
} 

Post Model

<?php

class Post extends Eloquent{

    /**
     * @var string Table
     */
    protected $table = 'posts';

    public function comments()
    {
        return $this->morphMany('Comment', 'commentable');
    }
} 

Now lets create our first comment for the topic with id 1:

$topic = Topic::find(1);
$topic->comments()->create(['body' => 'blah for topic', 'user_id' => Auth::id()]);

Now you should have your comment for the topic stored within the comments table , something that you should be aware of ,is that commentable_id field will have the id of the topic which is 1 and the commentable_type will store the model name which is Topic.

lets do the same thing for the post with Id of 2 :

$post= Post::find(2);
$post->comments()->create(['body' => 'blah for post', 'user_id' => Auth::id()]);

Now commentable_id will have the id of the post which is 2 and the commentable_type will store the model name which is Post.

Since now everything in place I can get the Topic comments and determine which user have left this comment like so:

$topic = Topic::find(1);
foreach($topic->comments as $comment)
{
  echo "Comment By: {$comment->user->username} <br />";
  echo $comment->body;
}

We can do the same thing for posts :

$post = Post::find(2);
foreach($post->comments as $comment)
{
  echo "Comment By: {$comment->user->username} <br />";
  echo $comment->body;
}
0 likes
8 replies
JarekTkaczyk's avatar

@xroot That's simple polymorphic 1-m relation, is there any trick around?

@xroot I mean, I'm not trying to be a d.ck saying that's nothing to show. I was really intrigued by the title and hoped to see something interesting, that's all. I suppose not everyone is familiar with polymorphic relations so it still can be useful.

anouarabsslm's avatar

@JarekTkaczyk the only trick here that you can determine the user made the comment by setting a relationship between the comments table and users , which may be not clear for someone new to this kind of relationship, even the laravel doc did not mention that you can add a foreign key to the table that hold polymorphic relationship .

1 like
xingfucoder's avatar

Great @xroot, thanks for sharing.

Any other trick you want to share here, you are welcome!

Please or to participate in this conversation.