Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you provide an example of a one-to-many polymorphic relationship in Laravel


Can you provide an example of a one-to-many polymorphic relationship in Laravel


Certainly! In Laravel, a one-to-many polymorphic relationship allows a model to belong to more than one other model on a single association. This is useful when multiple models can share the same type of related model.

One-to-Many Polymorphic Relationship in Laravel (Example)

Concept Overview

Imagine you have two different models:

- Post**
- Video**

Both of these models can have many comments. Instead of creating separate comment tables for posts and videos, you use a polymorphic relationship where the Comment model can belong to either a Post or a Video.

Step-by-Step Example

1. Define the Models

- Post (can have many comments)
- Video (can have many comments)
- Comment (belongs to either a Post or a Video)

2. Database Structure (Conceptual, no tables)

- The comments table will have:
- `id`
- `body` (the comment text)
- `commentable_id` (the ID of the related model, either Post or Video)
- `commentable_type` (the class name of the related model, e.g., `App\Models\Post` or `App\Models\Video`)
- timestamps (`created_at`, `updated_at`)

3. Model Setup

Comment Model (Belongs to commentable)

php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    // Define the polymorphic relationship
    public function commentable()
    {
        return $this->morphTo();
    }
}

Post Model (Has many comments)

php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // Define the polymorphic one-to-many relationship
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

Video Model (Has many comments)

php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    // Define the polymorphic one-to-many relationship
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

4. Usage Examples

Adding a comment to a Post

php
$post = Post::find(1);

$post->comments()->create([
    'body' => 'This is a comment on the post.'
]);

Adding a comment to a Video

php
$video = Video::find(1);

$video->comments()->create([
    'body' => 'This is a comment on the video.'
]);

Retrieving comments for a Post or Video

php
$postComments = Post::find(1)->comments;

$videoComments = Video::find(1)->comments;

Accessing the parent model from a comment

php
$comment = Comment::find(1);

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

Summary

- The Comment model uses `morphTo()` to belong to any model.
- The Post and Video models use `morphMany()` to define the one-to-many polymorphic relationship.
- The `commentable_id` and `commentable_type` columns in the comments table store the ID and class name of the parent model.
- This setup allows you to reuse the Comment model for multiple parent models without duplicating code or tables.

If you want, I can also provide the migration code for the comments table or further examples on querying polymorphic relationships!