Bird
Raised Fist0
Laravelframework~5 mins

Polymorphic relationships in Laravel

Choose your learning style10 modes available
Introduction

Polymorphic relationships let you connect one model to many different models using a single association. This saves time and keeps your database simple.

You want to add comments to posts, videos, and photos without making separate comment tables.
You want to tag different types of content like articles and products with the same tags.
You want to track likes or favorites on multiple models like posts and comments.
You want to attach images to different models like users, products, and categories.
Syntax
Laravel
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

// In Comment model
public function commentable()
{
    return $this->morphTo();
}

The morphMany method defines the polymorphic one-to-many side.

The morphTo method defines the inverse side that can belong to any model.

Examples
This lets a post have many comments.
Laravel
class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}
This lets a video have many comments using the same comments table.
Laravel
class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}
This lets a comment belong to either a post or a video.
Laravel
class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}
Sample Program

This example shows how comments can belong to either posts or videos using polymorphic relationships. The commentable_type and commentable_id fields tell Laravel which model the comment belongs to.

Laravel
<?php

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}

// Usage example
$post = new Post();
$post->id = 1;

$video = new Video();
$video->id = 2;

$comment1 = new Comment();
$comment1->id = 101;
$comment1->commentable_type = Post::class;
$comment1->commentable_id = $post->id;

$comment2 = new Comment();
$comment2->id = 102;
$comment2->commentable_type = Video::class;
$comment2->commentable_id = $video->id;

// Simulate fetching commentable model
function getCommentableModel(Comment $comment) {
    match ($comment->commentable_type) {
        Post::class => print("Comment {$comment->id} belongs to Post {$comment->commentable_id}\n"),
        Video::class => print("Comment {$comment->id} belongs to Video {$comment->commentable_id}\n"),
        default => print("Unknown commentable type\n"),
    };
}

getCommentableModel($comment1);
getCommentableModel($comment2);
OutputSuccess
Important Notes

Remember to add commentable_type and commentable_id columns in your comments table.

Polymorphic relationships reduce the need for multiple tables for similar relations.

Summary

Polymorphic relationships let one model relate to many different models.

Use morphMany on the owning models and morphTo on the related model.

This keeps your database simple and your code clean.

Practice

(1/5)
1. What is the main purpose of polymorphic relationships in Laravel?
easy
A. To allow a model to belong to more than one other model on a single association
B. To create many-to-many relationships between two models
C. To enforce strict foreign key constraints in the database
D. To automatically generate database migrations

Solution

  1. Step 1: Understand polymorphic relationships

    Polymorphic relationships allow a model to belong to multiple other models using a single association.
  2. Step 2: Compare with other relationship types

    Unlike many-to-many or one-to-many, polymorphic lets one model relate to different models without separate foreign keys.
  3. Final Answer:

    To allow a model to belong to more than one other model on a single association -> Option A
  4. Quick Check:

    Polymorphic relationships = single association to multiple models [OK]
Hint: Polymorphic = one model relates to many different models [OK]
Common Mistakes:
  • Confusing polymorphic with many-to-many relationships
  • Thinking it automatically creates migrations
  • Assuming it enforces database constraints
2. Which method should you use in the related model to define a polymorphic relationship?
easy
A. morphTo()
B. hasMany()
C. belongsToMany()
D. morphMany()

Solution

  1. Step 1: Identify the related model method

    The related model uses morphTo() to define the polymorphic inverse relationship.
  2. Step 2: Differentiate from owning model methods

    Owning models use morphMany(), but the related model uses morphTo().
  3. Final Answer:

    morphTo() -> Option A
  4. Quick Check:

    Related model uses morphTo() [OK]
Hint: Related model always uses morphTo() for polymorphic [OK]
Common Mistakes:
  • Using morphMany() in the related model
  • Confusing belongsToMany() with polymorphic
  • Using hasMany() instead of morphTo()
3. Given the following code, what will $comment->commentable->name output?
class Comment extends Model {
  public function commentable() {
    return $this->morphTo();
  }
}

$comment = Comment::find(1);

Assuming the comment belongs to a Post with name = 'Laravel Tips'.
medium
A. Error: Undefined property 'name'
B. 'Laravel Tips'
C. null
D. 'Comment'

Solution

  1. Step 1: Understand morphTo() behavior

    The commentable() method returns the related model instance, here a Post.
  2. Step 2: Access the related model's property

    Accessing name on the Post model returns 'Laravel Tips'.
  3. Final Answer:

    'Laravel Tips' -> Option B
  4. Quick Check:

    commentable->name = 'Laravel Tips' [OK]
Hint: morphTo() returns related model instance [OK]
Common Mistakes:
  • Expecting null if not eager loaded
  • Confusing property with method call
  • Assuming error without checking model relation
4. What is wrong with this polymorphic relationship definition?
class Image extends Model {
  public function imageable() {
    return $this->morphMany();
  }
}
medium
A. morphMany() requires parameters but none are given
B. No relationship method is needed in Image model
C. The method name should be morphable()
D. The method should be morphTo(), not morphMany()

Solution

  1. Step 1: Identify the model role

    Image is the related model, so it should use morphTo() for polymorphic inverse.
  2. Step 2: Check method used

    morphMany() is for owning models, not related models.
  3. Final Answer:

    The method should be morphTo(), not morphMany() -> Option D
  4. Quick Check:

    Related model uses morphTo() [OK]
Hint: Related model must use morphTo(), not morphMany() [OK]
Common Mistakes:
  • Using morphMany() without parameters
  • Wrong method name for polymorphic inverse
  • Thinking no method is needed
5. You want to create a polymorphic relationship where both Post and Video models can have many Comment models. Which of the following is the correct way to define the relationship in the Post model?
hard
A. public function comments() { return $this->belongsToMany(Comment::class); }
B. public function comments() { return $this->hasMany(Comment::class); }
C. public function comments() { return $this->morphMany(Comment::class, 'commentable'); }
D. public function comments() { return $this->morphTo(Comment::class, 'commentable'); }

Solution

  1. Step 1: Identify owning model relationship

    Post owns many comments via polymorphic relation, so use morphMany().
  2. Step 2: Use correct parameters

    morphMany() requires the related model class and the polymorphic name 'commentable'.
  3. Final Answer:

    public function comments() { return $this->morphMany(Comment::class, 'commentable'); } -> Option C
  4. Quick Check:

    Owning model uses morphMany() with polymorphic name [OK]
Hint: Owning model uses morphMany() with polymorphic name [OK]
Common Mistakes:
  • Using hasMany() instead of morphMany()
  • Using morphTo() in owning model
  • Using belongsToMany() for polymorphic
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard