Polymorphic relationships let you connect one model to many different models using a single association. This saves time and keeps your database simple.
Polymorphic relationships in 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.
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(); } }
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.
<?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);
Remember to add commentable_type and commentable_id columns in your comments table.
Polymorphic relationships reduce the need for multiple tables for similar relations.
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
Solution
Step 1: Understand polymorphic relationships
Polymorphic relationships allow a model to belong to multiple other models using a single association.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.Final Answer:
To allow a model to belong to more than one other model on a single association -> Option AQuick Check:
Polymorphic relationships = single association to multiple models [OK]
- Confusing polymorphic with many-to-many relationships
- Thinking it automatically creates migrations
- Assuming it enforces database constraints
Solution
Step 1: Identify the related model method
The related model usesmorphTo()to define the polymorphic inverse relationship.Step 2: Differentiate from owning model methods
Owning models usemorphMany(), but the related model usesmorphTo().Final Answer:
morphTo() -> Option AQuick Check:
Related model uses morphTo() [OK]
- Using morphMany() in the related model
- Confusing belongsToMany() with polymorphic
- Using hasMany() instead of morphTo()
$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'.Solution
Step 1: Understand morphTo() behavior
Thecommentable()method returns the related model instance, here a Post.Step 2: Access the related model's property
Accessingnameon the Post model returns 'Laravel Tips'.Final Answer:
'Laravel Tips' -> Option BQuick Check:
commentable->name = 'Laravel Tips' [OK]
- Expecting null if not eager loaded
- Confusing property with method call
- Assuming error without checking model relation
class Image extends Model {
public function imageable() {
return $this->morphMany();
}
}Solution
Step 1: Identify the model role
Image is the related model, so it should usemorphTo()for polymorphic inverse.Step 2: Check method used
morphMany()is for owning models, not related models.Final Answer:
The method should be morphTo(), not morphMany() -> Option DQuick Check:
Related model uses morphTo() [OK]
- Using morphMany() without parameters
- Wrong method name for polymorphic inverse
- Thinking no method is needed
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?Solution
Step 1: Identify owning model relationship
Post owns many comments via polymorphic relation, so usemorphMany().Step 2: Use correct parameters
morphMany()requires the related model class and the polymorphic name 'commentable'.Final Answer:
public function comments() { return $this->morphMany(Comment::class, 'commentable'); } -> Option CQuick Check:
Owning model uses morphMany() with polymorphic name [OK]
- Using hasMany() instead of morphMany()
- Using morphTo() in owning model
- Using belongsToMany() for polymorphic
Ready to prove it?
Pass the test and this pattern moves unknown
