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

spiritkiddie's avatar

Multiple query on same model

I have a post model with different categories and number of views. I want to show only popular posts by views in one section whiles featured post in another section and one post category in another section on the same page, and this is how i approach it.

    $pressrelease = Post::query()->pressReleases()->get();
    $popular = Post::query()->popular()->get();
    $featured = Post::query()->featured()->get();

This approach make multiple query on same model, so i changed it to this approach.

	$post = Post::query();
	$pressrelease = $post->pressReleases()->get();
    $popular = $post->popular()->get();
    $featured = $post->featured()->get();

This approach the queries don't work as expected because it overrides each other. Any advice on how to approach this?

0 likes
4 replies
LaryAI's avatar
Level 58

The issue with the second approach is that the $post variable is being modified by each subsequent query, so the final query is only returning the results of the featured() method.

One solution would be to use separate instances of the Post model for each query. This way, each query is independent and won't interfere with the others. Here's an example:

$pressrelease = Post::query()->pressReleases()->get();
$popular = Post::query()->popular()->get();
$featured = Post::query()->featured()->get();

Alternatively, you could use the clone keyword to create a copy of the $post variable for each query. This way, each query is working with a separate instance of the Post model. Here's an example:

$post = Post::query();
$pressrelease = clone $post;
$popular = clone $post;
$featured = clone $post;

$pressrelease = $pressrelease->pressReleases()->get();
$popular = $popular->popular()->get();
$featured = $featured->featured()->get();

Note that in the second approach, we're using the clone keyword to create separate instances of the $post variable for each query. Then, we're running each query on its own instance of the Post model.

1 like
Snapey's avatar
Snapey
Best Answer
Level 122

If your second approach had worked, then it would also result in three queries.

Lary's 'solution' is also three queries. No advantage over your existing code.

Since you will likely have the same posts turning up in each query, other methods such as a single query with grouping is likely to have other issues.

Best solution is your original.

If you are concerned about performance, you can cache each query so that refreshing the page (or returning to it from looking at an individual post) would result in zero queries.

1 like
Snapey's avatar

@spiritkiddie

$pressrelease = cache()->remember('pressrelease', 60*60, function () {
    return Post::query()->pressReleases()->get();
});

will cache the result of the query for 1 hour, under a cache key of pressrelease

repeat for the other queries

You might want to consider clearing the specific cache keys when adding or updating a post

1 like

Please or to participate in this conversation.