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

iamxquisite's avatar

Laravel Eloquent - How can I filter a query and re-use it for different variables.

I previously wrote some code but now that I'm looking at it about a year I feel like there has to be a more optimized way of getting the same result.

I have a Model for Items, the Items have a 'type' attribute. This is how I am currently getting the Items by type, using Item::where('type','foo')->get(); In total this is running the same query 5 times.

$meats = Item::where('type', 'Meat')->get();
$premiums = Item::where('type', 'Premium')->get();
$drinks = Item::where('type', 'Drink')->get();
$sodas = Item::where('type', 'Soda')->get();
$sides = Item::where('type', 'Side')->get();

I came up with this solution yesterday but I feel like it's kind of ugly. Both of the solutions work but my question is, what is the proper way of doing it?

$items = Item::all();

    foreach($items as $item){
        if($item->type == 'Meat'){
            $meats[] = $item;
        }
        if($item->type == 'Premium'){
            $premiums[] = $item;
        }
        if($item->type == 'Drink'){
            $drinks[] = $item;
        }
        if($item->type == 'Soda'){
            $sodas[] = $item;
        }   
        if($item->type == 'Side'){
            $sides[] = $item;
        }
    }
0 likes
8 replies
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Are those all the possible types or are there more?

You can do this if it isn't

$items = Item::whereIn('type', ['Meat', 'Premium', 'Drink', 'Soda', 'Side'])->get();

//and
$meats = $items->where('type', 'Meats');
2 likes
automica's avatar

@iamxquisite for clarification, @sinnbeck approach above

  • does a single query for all possible types you want to list and returns it as a collection
  • then fIlters the collection, in this case, by type=Meat to get a list of meats.

Filtering collections is much cheaper than doing DB queries as you have the results already in memory.

2 likes
iamxquisite's avatar

@sinnbeck Thanks for your reply. Those are all the types but I know doing it the way I had it is taxing the DB.

@automica thank you for the explanation makes sense, wasn’t sure if getting a collection would run a query every time I used the where() on it. But now i know it’s just one query.

These are all of the types in the Item:: model, would running the code below work as well

$items = DB::table(‘items’)->get();
$meats = $items->where(‘type’, ‘Meat’)

Sinnbeck's avatar

That would not get models, so it depends on whether you need that or not. I personally prefer the eloquent way, but that should work as well

And if you need all records you don't need the whereIn

iamxquisite's avatar

@sinnbeck thanks again so can I run the

$items = Item::all();

Would that allow me to use the where() for each variable.

MichalOravec's avatar

@iamxquisite What about

$items = Item::whereIn('type', ['Meat', 'Premium', 'Drink', 'Soda', 'Side'])->get()->groupBy('type');

return view('some-view', compact('items'));

And here just an example for meats

@foreach ($meats = $items->get('Meat') as $meat)
    {{ $meat->id }}
@endforeach
1 like
extjac's avatar

what about something like that....

$meats = Item::findType('Meat')->get();  //you can also pass an array

Item Model

public static function findType( $type )
{
	return Self::where('type', $type); //you can also do whereIn( array() )
}

Please or to participate in this conversation.