DEV Community

Cover image for Laravel Polymorphic Relationships – Complete Guide
Muhammmad Nawaz
Muhammmad Nawaz

Posted on • Originally published at invidiatech.com

Laravel Polymorphic Relationships – Complete Guide

Polymorphic relationships in Laravel allow a model to belong to more than one other model using a single association.

They are especially useful when multiple models share the same kind of relationship — such as comments, likes, tags, or images.

When to Use Polymorphic Relationships?Use polymorphic relationships when:

  • You have a single model (e.g. Comment) that can belong to multiple other models (e.g. Post, Video, Product)- You don’t want to create separate foreign keys or tables for each relationship type.## Example Use Case: Comments on Posts and VideosLet’s say you want to allow users to comment on both blog posts and videos.

Instead of creating two separate tables like post_comments and video_comments, you can create one comments table using polymorphic relationships.

Step-by-Step Implementation### 1. Create Models & MigrationsRun:

php artisan make:model Post -m
php artisan make:model Video -m
php artisan make:model Comment -m

2. Posts Table Migration (database/migrations/xxxx_create_posts_table.php)Schema::create('posts', function (Blueprint $table) {

$table->id();
$table->string('title');
$table->timestamps();
Enter fullscreen mode Exit fullscreen mode

});

3. Videos Table MigrationSchema::create('videos', function (Blueprint $table) {

$table->id();
$table->string('title');
$table->timestamps();
Enter fullscreen mode Exit fullscreen mode

});

4. Comments Table MigrationSchema::create('comments', function (Blueprint $table) {

$table->id();
$table->text('body');

// Polymorphic relation fields
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');

$table->timestamps();
Enter fullscreen mode Exit fullscreen mode

});
Here, commentable_id and commentable_type determine the model (Post or Video) the comment belongs to.### 5. Define Relationships in Models#### In Comment.php:namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
protected $fillable = ['body'];

public function commentable()
{
    return $this->morphTo();
}
Enter fullscreen mode Exit fullscreen mode

}

In Post.php:namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
protected $fillable = ['title'];

public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}
Enter fullscreen mode Exit fullscreen mode

}

In Video.php:namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
protected $fillable = ['title'];

public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}
Enter fullscreen mode Exit fullscreen mode

}

6. Using the Relationship (Example)#### Create Post and Add Comment:$post = Post::create(['title' => 'Laravel Polymorphic Tutorial']);

$post->comments()->create(['body' => 'Great article!']);

Create Video and Add Comment:$video = Video::create(['title' => 'Laravel Video']);

$video->comments()->create(['body' => 'Awesome tutorial!']);

7. Accessing Comments#### Get all comments of a post: $post = Post::find(1);

foreach ($post->comments as $comment) {
echo $comment->body;
}

Get the parent of a comment:$comment = Comment::find(1);

$parent = $comment->commentable; // Could be Post or Video

Reverse: One Model with Many Parent ModelsThe power of polymorphic is that you can go both ways:

  • $post->comments → all comments for the post- $comment->commentable → the post or video it belongs to## Real-Life Use Cases- comments → for posts, products, videos, etc.- images → for users, posts, categories- tags → for articles, videos, photos- likes → for any content## Tips & GotchasTipDescriptionUse correct typecommentable_type must store full class name (App\Models\Post)morphTo() magicLaravel auto-resolves based on *_id and *_typeIndex columnsAdd indexes on commentable_id and commentable_type for speedUse with()Eager load relationships to reduce queries

Bonus: Migration Index Example$table->index(['commentable_id', 'commentable_type']);

SummaryFeatureBenefitmorphTo()Allows one model to belong to multiple typesmorphMany() / morphOne()Used by the parent modelsReduces tablesClean design, less duplicationGood for shared behaviorsLike comments, tags, uploads

**

ConclusionLaravel’s polymorphic relationships** are a powerful way to manage shared relationships across multiple models. They save you from writing repetitive code and keep your database clean and efficient.

Top comments (0)