Filter Polymorphic Relationships Cleanly in Laravel Using whereHasMorph()

Apply conditions on polymorphic relations without messy query logic.

  • 07 May, 2026
  • 24 Views

Filter Polymorphic Relationships Cleanly in Laravel Using whereHasMorph()

In Laravel, polymorphic relationships are powerful for structures like:

  • Comments
  • Activities
  • Notifications

Example:

A comment may belong to:

  • Post
  • Video
  • Product

Example Relationship

public function commentable()
{
    return $this->morphTo();
}

The Challenge

Filtering polymorphic types manually becomes messy.

Laravel provides a clean solution:

whereHasMorph()

Basic Usage

Comment::whereHasMorph(
    'commentable',
    [Post::class],
    function ($query) {
        $query->where('published', true);
    }
)->get();

What This Does

  • Finds comments belonging to posts
  • Filters only published posts

Multiple Morph Types

Comment::whereHasMorph(
    'commentable',
    [Post::class, Video::class],
    function ($query) {
        $query->where('is_active', true);
    }
)->get();

👉 Same condition applied across multiple morph models.


Real Project Example

Imagine activity logs:

Activity::whereHasMorph(
    'subject',
    [Order::class, Payment::class],
    fn ($q) => $q->where('status', 'completed')
)->get();

Why This Is Useful

It helps you:

  • Filter morph relations cleanly
  • Avoid manual type checks
  • Keep queries maintainable
  • Handle multi-model systems elegantly

When to Use It

Use whereHasMorph() when:

  • Working with morphTo() relationships
  • Filtering multiple model types
  • Building activity or comment systems 

Share: