Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ozan's avatar
Level 32

Polymorphic Relationships Customized Eager Loading

I have a Post model related with Like model with the morphTo() relationship.

I only want to get the counts of likes for a post but this gives me the same result.

return Post::with(['owner', 'tags', 'likes' => function($query)
        {
            $query->count();
        }])->where('slug', $slug)->first();

What should I do?

0 likes
6 replies
JarekTkaczyk's avatar

@Ozan I suppose you got all you need already, so I will just add one important thing about eager loading: You don't execute the query within the eager loading closure. The reason is, that from this closure only query builder is returned and eloquent doesn't know that you already fetched the result.

I use returned above because in fact it is not returned, even if you return any value it will be ignored. Eloquent simply adds constraints from the closure and executes the query later.

And count is one of methods that execute the query.

The only way to use that query and its result is to assign it to the variable passed by reference - something that I mentioned in this forum, like this:

Model::with(['relation' => function ($q) use (&$result) {
  $result = $q->get() / count() / whatever..
}])->find(..) / get();
1 like
StormShadow's avatar

I too had this problem as Laravel's new $withCount doesn't seem to work with Polymorphic relationships as of yet. I hope this code will help someone down the line.

  public function likesCount()
    {
       return $this->morphOne(Like::class, 'likeable')
            ->selectRaw('likeable_id, count(*) as aggregate')
            ->groupBy('likeable_id');

    }

    public function getLikesCountAttribute()
    {

        $this->load('likesCount');

        $related = $this->getRelation('likesCount');

        return ($related) ? (int) $related->aggregate : 0;
    }
1 like
orphanedrecord's avatar

I had a similar situation (using Laravel 5.6) where a specialized class morphs (using morphOne) to a more general class. The general class has many related records that I wanted a count of via the specialized index page. Hope that makes sense!

In order to eager load the count of related records from the specialized repo, I used Eager Loading Constraints, with a query builder calling the ->withCount('related').

public function paginate(int $number)
{
    $specifics = $this->specific
        ->with(['general' => function ($query) {
            $query->withCount('related');
        }])
        ->orderBy('id', 'desc')
        ->paginate($number);

    return $specifics;
}

For a bit more clarity the ->withCount('related') references a hasMany relationship defined in the General model.

Please or to participate in this conversation.