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

AsnCode's avatar

exists() methods cause some n + 1 query

Hello i have an app that cause me many + 1 duplicate query, with the help of N + 1 query detector from spatie i have isolate the problem :

public function hasLiked(Post $post): bool
    {
        return $post
            ->likes()
            ->where('user_id', $this->id)
            ->exists();
    }

inside my laravel debugbar :

select exists(select * from "likes" where "likes"."post_id" = 3 and "likes"."post_id" is not null and "user_id" = 1) as "exists"

When i made a @foreach inside my index actions i think the call of this method ( that detect if a post is liked or cause me this problem but i dont know how to resole this .... ^^

LIKE MODEL

public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

Post

function likes() : HasMany
    {
        return $this->hasMany(Like::class);
    }

USER

public function hasLiked(Post $post): bool
    {
        return $post
            ->likes()
            ->where('user_id', $this->id)
            ->exists();
    }

Thanks you :)

0 likes
4 replies
Tray2's avatar

Of course it gives you an n+1 issue, I would suggest you using ->withCount('likes') on the original query.

Post::withCount('likes')->paginate(50):
1 like
Snapey's avatar
Snapey
Best Answer
Level 122

if you eager load the likes relationship when loading posts, you can check if the user_id is present in the likes collection?

    public function hasLiked(Post $post): bool
    {
        $post->loadMissing('likes');

        return $post->likes->contains('user_id', $this->id);
    }

loadMissing will fetch the likes if they are not loaded, so make sure you eager load them before calling this

1 like
Snapey's avatar

thats good, please mark it solved by selecting best answer

Please or to participate in this conversation.