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

Fluber's avatar

Laravel do one query

I have model post. I use this package: https://github.com/cyrildewit/eloquent-viewable

I have accesor in model post:

protected $appends = ['views'];

public function getViewsAttribute()
{
    return $this->views()->count();
}

In blade when I foreach my posts:

@foreach($posts as $post)
     Views: {{ $post->views }} {{ trans_choice('trans.views', $post->views)
@endforeach

I get two queries with views. And if posts 100, then queries will be 200.. For each post I get two same queries. How I can resolve this? If I delete {{ trans_choice('trans.views', $post->views) Then I get one query.

0 likes
5 replies
manelgavalda's avatar

@DRONAX - You can use the withCount method above or if you want to use your method:

When you are doing this:

$this->views()->count()

You are using the query builder to count your views() relation: If you want to use your accesor without doing the 100 queries you need to load the relation before using it, and using the collection count:

protected $appends = ['views'];

public function getViewsAttribute()
{
    return $this->views->count(); //removed the () in views so you are working with collections instead. 
}

Then your $posts variable query needs to eager load your views relation:

$posts = App\Post::with('views')->get();

And you will end up with one query using your method.

Mithrandir's avatar

You are not using the views attribute, you are calling the views relationship.

return $this->views()->count();

performs a query every time it is called

return $this->views->count();

does not.

But the solution by @manelgavalda is better

Mithrandir's avatar

Also, you should look up what the $appends property does as it is not eager loading.

Please or to participate in this conversation.