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

ownmaster's avatar

Ensure only one single record is returned by Eloquent query

I checked Laravel collection methods and can't understand - is there a method for Eloquent query to ensure that exactly 1 record is returned - not 0 and not more than 1? Something like singleOrFail(). As an example, in Entity Framework there is First() which works like Laravel's firstOrFail() and there is also Single().

Or, is it not implemented (yet)?

0 likes
6 replies
tykus's avatar

first() returns the a Model instance matching whatever went before in the Eloquent/Query Builder - it returns null if nothing is found.

firstOrFail() will throw a ModelNotFoundException if nothing is found.

Exactly one record can be returned only if at least one record exists!

Alamin's avatar

You can use ->first()

Like Enployee::where('salary',2000)->first();

ownmaster's avatar

No, the idea here is different.

Example #1. There is 1 employee with 'salary' = 1000 in the database. Employee::where('salary', 1000)->firstOrFail() will return this employee.

Example #2. There are 2 employees with 'salary' = 1000 in the database. Employee::where('salary', 1000)->firstOrFail() will return one of them.

Example #3. There are no employees with 'salary' = 1000 in the database. In this case Employee::where('salary', 1000)->firstOrFail() will raise an exception.

The idea of method I'm talking about (singleOrFail()) is that it will raise an exception not only in example #3 (because there are no matching users), but also in example #2 (because there are many matching users).

1 like
tykus's avatar
tykus
Best Answer
Level 104

In that case, extend the query builder with a macro (in a ServiceProvider)

\Illuminate\Database\Query\Builder::macro('singleOrFail', function () {
    $result = $this->get();
    if ($result->count() == 1) {
        return $result->first();
    }
    throw new \Exception; 
});
1 like
deansatch's avatar
Employee::where('salary', 1000)
->groupBy('salary')
->havingRaw('COUNT(salary) = 1')
->first();

jjudge's avatar

Just to close off this six-year-old thread, the method being saught here is sole().

$query->sole() will return exactly one record. If no records match, an exception will be thrown. If more than one record matches, also an exception will be thrown.

1 like

Please or to participate in this conversation.