PHP
Implementing Eloquent Polymorphic Relationships for Flexible Associations
Discover how to use Laravel Eloquent polymorphic relationships to define a single association that can belong to multiple different models, simplifying complex database structures.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
// Post Model
class Post extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
// Video Model
class Video extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
// Comment Model
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
/*
// Migration for the 'comments' table would look like this:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('body');
$table->morphs('commentable'); // Adds commentable_id (integer) and commentable_type (string)
$table->timestamps();
});
*/
// Usage:
// $post = Post::find(1);
// foreach ($post->comments as $comment) {
// echo $comment->body;
// }
// $video = Video::find(5);
// foreach ($video->comments as $comment) {
// echo $comment->body;
// }
// $comment = Comment::find(10);
// $parent = $comment->commentable; // Can be a Post or a Video instance
How it works: Polymorphic relationships allow a model to belong to more than one other model on a single association. In this snippet, `Post` and `Video` models can both have `Comment` models associated with them, sharing a single `comments` table. The `morphMany` method is used on the parent models (`Post`, `Video`) to define the relationship, while `morphTo` is used on the `Comment` model to retrieve its associated parent. The `commentable_id` and `commentable_type` columns (created by `morphs()` in the migration) store the ID and type of the parent model, respectively, enabling this flexible association.