Updated June 2026. Tested on Laravel 13 and PHP 8.4.
Often you do not want a set of records, you want one. Eloquent gives you a few ways to pull a single model, and a couple of them tie in neatly with how Laravel handles missing records.
Find by primary key
find takes a primary key and returns that one model, or null if there is no match.
use App\Models\Product;
$product = Product::find(1);
Pass an array of keys and you get back a collection of the ones that exist.
$products = Product::find([1, 2, 3]);
First matching a condition
When you are filtering rather than looking up by key, first returns the first row that matches, or null.
$product = Product::where('is_active', true)->first();
Fail loudly with findOrFail
In a controller you usually want a missing record to become a 404 rather than a null that blows up later. findOrFail and firstOrFail throw a ModelNotFoundException when nothing is found, and Laravel turns that exception into a 404 response for you.
use App\Models\Product;
$product = Product::findOrFail(1);
$product = Product::where('price', '>', 1000)->firstOrFail();
So in a route you can return the model directly, with no manual check.
Route::get('/api/products/{id}', function (string $id) {
return Product::findOrFail($id);
});
Let route model binding do it
Even cleaner, if you type hint the model in a controller or route and name the wildcard to match, Laravel looks the record up for you and 404s automatically if it is missing.
Route::get('/products/{product}', function (Product $product) {
return $product;
});
There was no find call at all. Laravel saw the Product type hint, matched the {product} id, and fetched it. This is the approach I reach for most.
That is single record retrieval: find and first for a nullable result, the OrFail variants for an automatic 404, and route model binding when the record comes straight from the URL. Questions welcome below.
All comments ()
No comments yet
Be the first to leave a comment on this post.