Video Version of the Lesson
[Only for premium members]
[Only for premium members]
[Only for premium members]
When working with Eloquent ORM, there's a danger of using collection operations (like filter()
and map()
) on Eloquent results instead of applying conditions at the DB query level.
Consider this common approach:
$listings = Listing::with('tags')->latest()->get(); if ($request->has('s')) { $searchTerm = $request->input('s'); $listings = $listings->filter(function($listing) use ($searchTerm) { return str_contains($listing->title, $searchTerm) || str_contains($listing->company, $searchTerm) || str_contains($listing->location, $searchTerm); });} if ($request->has('tag')) { $tag = $request->input('tag'); $listings = $listings->filter(function($listing) use ($tag) { return $listing->tags->contains('slug', $tag); });} // Then take only what we need$listings = $listings->take(10);
This might seem clean and work well with small amounts of data. However, it introduces two critical issues:
I have created a simple job board application page and seeded 4000 listings. On the front end, I show only the ten latest listings, as seen in the code above. The search and tag filtering is done via the filter()
method from a Collection.
Using collection operations (filter()
after get()
) we have a few problems:
Despite only displaying 10 listings on the homepage, we're loading EVERY listing into memory! While the page loads relatively fast with many users, your application can run out of memory quickly.
The correct approach is to build the query progressively and only execute it when a condition is...