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

muuucho's avatar
Level 11

Refactor a part of a query to a Trait

I have this query:

$cruds = Crud::inTeamActive()->with([
            'color' => function ($q) {
                $q->where('deleted', 0);
            }->get();

I use the with() over and over in many controllers, so I like to refactor it to a Trait since is always the same where() statement attached. Sometimes I have multiple withs, with(['color', 'size', ...]) each having the same where clauses:

            'whatever' => function ($q) { $q->where('deleted', 0); }              

So, I like to write a trait method that accepts an array of the relations I want to get, so the Eloquent should replace the with() with a trait withWhere(), like

->withWhere(['color', 'animal', 'author', ...])

and a trait method:

public function scopeWithWhere($q, $withs)
    {
        foreach ($withs as $with) {
            return $q->where('deleted', 0);
        }
    }

Running the query, however, returns a collection where the WithWhere() is ignored. What I can see is that the function scopeWithWhere() don't use the $with, how should I get it right?

0 likes
3 replies
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Something like this. Untested

public function scopeWithWhere($q, $withs)
    {
    foreach ($withs as $with) { 
         $calls[$with] = function ($q) {
                $q->where('deleted', 0);
            };
     }
      $q->with($calls);
}

Or

public function scopeWithWhere($q, $withs)
    {
    foreach ($withs as $with) { 
         $q->with([$with => function ($q) {
                $q->where('deleted', 0);
            }]);
     }
      
}  
1 like
tykus's avatar

Should be implemented as :

public function scopeWithWhere($q, $relations)
{
    foreach ($relations as $relation) {
        $q->with([$relation => fn ($q) => $q->where('deleted', 0)]);
    }
}
1 like

Please or to participate in this conversation.