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.