PHP
Implementing Flexible Polymorphic One-to-Many Relationships in Laravel
Understand how to create versatile polymorphic relationships in Eloquent, allowing a model to belong to multiple different models on a single association.
<?php
// Example: A Comment can belong to either a Post or a Video.
// app/Models/Comment.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
// app/Models/Video.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
// Usage Example (e.g., in a controller or seeder):
$post = App\Models\Post::find(1);
$post->comments()->create(['content' => 'Great post!']);
$video = App\Models\Video::find(5);
$video->comments()->create(['content' => 'Awesome video!']);
// Retrieving comments for a post:
foreach ($post->comments as $comment) {
echo "Post Comment: " . $comment->content . "
";
}
// Retrieving the parent of a comment:
$comment = App\Models\Comment::find(1);
$commentable = $comment->commentable; // Can be a Post or a Video instance
if ($commentable instanceof App\Models\Post) {
echo "Comment belongs to Post: " . $commentable->title . "
";
} elseif ($commentable instanceof App\Models\Video) {
echo "Comment belongs to Video: " . $commentable->title . "
";
}
How it works: Polymorphic relationships allow a single model to belong to more than one other model, using a single association. This is incredibly useful when you have a common feature (like comments, tags, or images) that can be associated with various different model types. In this example, a `Comment` model can belong to either a `Post` or a `Video`. The `morphTo()` method on the `Comment` model defines the relationship, while `morphMany()` (or `morphOne()`) on `Post` and `Video` models establishes their side of the relationship. Laravel handles the necessary `_type` and `_id` columns automatically, providing a flexible and clean way to manage such associations.