Polymorphic Relationship in Laravel: What It Is and How It Works
polymorphic relationship in Laravel allows a model to belong to more than one other model on a single association. It lets you use one table to relate to multiple different models without needing separate foreign keys for each model type.How It Works
Imagine you have different types of content like posts and videos, and you want users to be able to comment on both. Instead of creating separate comment tables or foreign keys for posts and videos, Laravel's polymorphic relationship lets a single comments table connect to both.
This works by storing two pieces of information in the comments table: the ID of the related model and the type of that model (like 'Post' or 'Video'). This way, Laravel knows which model the comment belongs to, no matter if it's a post or a video.
It's like having a universal connector that adapts to different plugs, making your database simpler and your code cleaner.
Example
This example shows how to set up a polymorphic relationship where comments can belong to either posts or videos.
<?php // Post.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { public function comments() { return $this->morphMany(Comment::class, 'commentable'); } } // Video.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Video extends Model { public function comments() { return $this->morphMany(Comment::class, 'commentable'); } } // Comment.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Comment extends Model { public function commentable() { return $this->morphTo(); } } // Migration for comments table use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateCommentsTable extends Migration { public function up() { Schema::create('comments', function (Blueprint $table) { $table->id(); $table->text('body'); $table->unsignedBigInteger('commentable_id'); $table->string('commentable_type'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('comments'); } } // Usage example $post = Post::find(1); $post->comments()->create(['body' => 'Great post!']); $video = Video::find(1); $video->comments()->create(['body' => 'Nice video!']); // Fetching comments foreach ($post->comments as $comment) { echo $comment->body . "\n"; } foreach ($video->comments as $comment) { echo $comment->body . "\n"; }
When to Use
Use polymorphic relationships when you want a single model to belong to multiple other models without creating many separate tables or foreign keys. This is common for features like comments, tags, or likes that can apply to different content types.
For example, if you have a blog with posts and videos, and both can have comments or tags, polymorphic relationships keep your database simple and your code easy to maintain.
It helps avoid duplication and makes adding new related models easier without changing your database structure.
Key Points
- Polymorphic relationships allow one model to belong to multiple other models using a single association.
- They use
commentable_idandcommentable_typecolumns to track the related model. - This pattern reduces database complexity and code duplication.
- Commonly used for comments, tags, likes, or any feature shared across different models.