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

jsprunk's avatar

WhereHas on multiple request variables

Hi there, I am new to Laravel and trying some stuff. I have three Models all with belongsToMany relationships (2 pivot tables). I want to filter the results using the pivot tables if an optional additional parameter is passed to the request.

The code below is doing exactly what I want, but it is quite verbose and when an additional parameter is added, it grows rapidly.

$object = request('object');
$thing = request('thing');

if($object && $thing)
{
     $users = User::whereHas('objects',function($query) use($object){
            $query->where('objects.id',$object);
        })->whereHas('things',function($query) use($thing) {
           $query->where('things.id',$thing);
        })->get();
}
else if($object)
{
      $users = User::whereHas('objects',function($query) use($object){
            $query->where('objects.id',$object);
        })->get();
}
else if($thing)
{
     $users = User::whereHas('things',function($query) use($thing) {
           $query->where('things.id',$thing);
        })->get();
}
else
{
    $users = User::all();
}

Does Eloquent provide a better solution where I can build the query step by step, depending on the parameter being set? Something like:

$builder = ???
if($object)
{
    $builder = $builder->whereHas('objects',...);
}
if($thing)
{
    $builder = $builder->whereHas('things',...);
}
$builder->get();
0 likes
4 replies
jsprunk's avatar

Hmm.. setting User::where('id','>',0); on the ??? is working, but I don't like it :)

jsprunk's avatar
$builder = User::query(); 

apparently does the trick. Never mind, I'll keep on practicing.

Swaz's avatar
Swaz
Best Answer
Level 20

You can use the when() method.

User::when(request('object'), function ($query) {
    $query->whereHas('objects', function ($query) {
        $query->where('objects.id', request('object'));
    });
})->when(request('thing'), function ($query) {
    $query->whereHas('things', function ($query) {
        $query->where('things.id', request('thing'));
    });
})->get();
1 like
jsprunk's avatar

Thanks, that was what I was looking for!

Please or to participate in this conversation.