Исключение MultipleRecordsFoundException
Исключение MultipleRecordsFoundException относится к категории исключений базы данных
в Laravel. Оно возникает в ситуациях, когда вы ожидаете получить единственную запись
из базы данных, а ваш запрос возвращает две или более записей. Это исключение
наследуется от RuntimeException и специально предназначено для случаев,
когда нарушается ожидание уникальности результата запроса.
Наиболее часто это исключение возникает при использовании методов
firstOrFail, sole и findOrFail, когда запрос находит
более одной записи, удовлетворяющей условиям. Также данное исключение
может появиться при работе с отношениями и попытке получить единственную
запись через метод first, если в запросе не указаны ограничения.
Синтаксис
Исключение выбрасывается автоматически при выполнении следующих методов:
<?php
// При использовании метода sole
Model::where('column', 'value')->sole();
// При использовании метода firstOrFail
Model::where('column', 'value')->firstOrFail();
// При использовании метода findOrFail
Model::findOrFail($id);
?>
Исключение можно перехватить и обработать с помощью конструкции
try-catch или в обработчике исключений приложения.
Пример
Рассмотрим пример, когда метод sole выбрасывает исключение
из-за нескольких записей в таблице:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\MultipleRecordsFoundException;
class UserController extends Controller
{
public function show()
{
try {
$user = User::where('status', 'active')->sole();
echo $user->name;
} catch (MultipleRecordsFoundException $e) {
echo "MultipleRecordsFoundException: " . $e->getMessage();
}
}
}
?>
Результат выполнения кода:
"MultipleRecordsFoundException: Found more than one record"
Пример
Обработка исключения при использовании метода firstOrFail
с несколькими записями:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Database\MultipleRecordsFoundException;
class PostController extends Controller
{
public function getPost()
{
try {
$post = Post::where('category_id', 1)->firstOrFail();
echo $post->title;
} catch (MultipleRecordsFoundException $e) {
echo "MultipleRecordsFoundException: " . $e->getMessage();
}
}
}
?>
Результат выполнения кода:
"MultipleRecordsFoundException: Found more than one record"
Пример
Обработка исключения в глобальном обработчике исключений с кастомизацией ответа для API:
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\MultipleRecordsFoundException;
use Throwable;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $exception)
{
if ($exception instanceof MultipleRecordsFoundException) {
return response()->json([
'error' => 'Multiple records found',
'message' => 'Your query returned more than one record'
], 409);
}
return parent::render($request, $exception);
}
}
?>
Результат выполнения кода при возникновении исключения:
{
"error": "Multiple records found",
"message": "Your query returned more than one record"
}
Пример
Правильный подход для предотвращения исключения - использование ограничений и условий, гарантирующих уникальность результата:
<?php
namespace App\Http\Controllers;
use App\Models\Product;
class ProductController extends Controller
{
public function getProduct($id)
{
$product = Product::where('id', $id)->first();
if ($product) {
echo $product->name;
} else {
echo "Product not found";
}
}
}
?>
Результат выполнения кода:
"Product name"
Смотрите также
-
исключение
ModelNotFoundException,
которое выбрасывается при отсутствии записей -
исключение
RecordsNotFoundException,
которое выбрасывается при отсутствии записей в коллекции -
исключение
QueryException,
которое выбрасывается при ошибках в SQL запросах -
исключение
UniqueConstraintViolationException,
которое выбрасывается при нарушении уникальности