When building modern Laravel applications, sometimes you need to associate a single model with more than one other model. Instead of duplicating relationship code, polymorphic relationships offer a clean, flexible way to handle these situations.
Letβs explore what polymorphic relationships are, how they work, and when to use them β with real-world code examples.
π What is a Polymorphic Relationship?
In Eloquent ORM, a polymorphic relationship allows a model to belong to more than one other model using a single association.
Example: You want to allow both posts and videos to have comments.
Rather than create two tables (post_comments
, video_comments
), you can use one comments
table with a polymorphic relationship.
π οΈ Setup: One-to-Many Polymorphic Relationship
Letβs build the classic example of posts and videos sharing the comments model.
1οΈβ£ Create Migrations
php artisan make:model Post -m
php artisan make:model Video -m
php artisan make:model Comment -m
posts table
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
videos table
Schema::create('videos', function (Blueprint $table) {
$table->id();
$table->string('url');
$table->timestamps();
});
comments table
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->morphs('commentable'); // Creates commentable_id & commentable_type
$table->timestamps();
});
2οΈβ£ Define Models and Relationships
Comment.php
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
Post.php
class Post extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
Video.php
class Video extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
3οΈβ£ Usage Example
Add a comment to a post
$post = Post::find(1);
$post->comments()->create([
'body' => 'Nice article!'
]);
Add a comment to a video
$video = Video::find(1);
$video->comments()->create([
'body' => 'Awesome video!'
]);
Get all comments of a post
$post->comments;
Get the parent of a comment
$comment = Comment::find(1);
$comment->commentable; // Returns Post or Video model
π Other Polymorphic Relationships
- β One-to-One Polymorphic
Example: An Image model can belong to both User and Product.
- β Many-to-Many Polymorphic
Example: A Tag model can be attached to both Posts and Videos.
π― When to Use Polymorphic Relationships
Use polymorphic relationships when:
- Multiple models share a common child (e.g., comments, likes, tags).
- You want to avoid creating separate tables for each parent-child pair.
- You value clean, maintainable relationships in your codebase.
π§ Final Thoughts
Polymorphic relationships are a powerful feature of Laravelβs Eloquent ORM. They simplify complex relationships and reduce duplication in your code. If you ever find yourself wanting multiple models to share a relationship, this is the tool for the job!
Let me know if you want a deep dive into many-to-many polymorphic relationships or custom polymorphic morph maps in a future post! π
Top comments (0)