Тайный метод firstOr()

Тайный метод firstOr()

Как бы ни была прекрасна документация Laravel, но в фреймворке еще много недокументированных функций и скрытых жемчужин. Одной из них является Eloquent-метод firstOr().

Впервые я узнал о нём из этого твита. Выглядело интригующим и я запрыгнул в эту кроличью нору, занявшись своим любимым видом спорта: ныряние в исходники Laravel.

Что делает firstOr()?

Этот метод, кажется, был добавлен в Laravel 5.4, и его можно найти в vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php. Выглядит знакомо, так как похоже на родственные методы — first() и firstOrFail(). В отличие от firstOrFail(), наш метод выполняет обратный вызов, если результат отсутствует, что может быть быть очень мощной фишкой, в зависимости от ваших потребностей.

Первый параметр — это массив столбцов, которые вы хотите извлечь из запроса (если есть результат). Второй параметр — упомянутый обратный вызов.

Давайте посмотрим на это в работе. Вот несколько примеров, иллюстрирующих, как вы можете это использовать.

Fail с Ответом

$r = App\User::where('id', 1)->firstOr(['name', 'email'], function () {
    return response()->json([
        'message' => 'Такого пользователя не существует.',
    ], 404);
});
Illuminate\Http\JsonResponse {#3474
     +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#3480},
     +original: [
       "message" => "Такого пользователя не существует.",
     ],
     +exception: null,
   }

Fail с Исключением

$r = App\User::where('id', 1)->firstOr(['name', 'email'], function () {
    throw new \Exception('Такого пользователя не существует.');
});
Exception {#3388
    #message: "Такого пользователя не существует.",
    #file: "...\vendor\psy\psysh\src\ExecutionLoopClosure.php(55) : eval()'d code",
    #line: 2,
}

Fail с Логом

$r = App\User::where('id', 1)->firstOr(['name', 'email'], function () {
    logger('Такого пользователя не существует.');
});

Тогда в laravel.log вы увидите:

[2019-06-02 21:14:03] local.DEBUG: Такого пользователя не существует.

Success

Успешный запрос возвращает объект коллекции Eloquent.

App\User {#3441
    name: "Mr. Leon Muller",
    email: "maiya57@example.net",
}

Если вам нужен массив, вы можете, разумеется, добавить toArray():

$r = App\User::where('id', 1)->firstOr(['name', 'email'], function () {
    throw new \Exception('Такого пользователя не существует.');
})->toArray();

Но есть альтернатива:

$r = App\User::where('id', 1)->firstOr(function() {
    throw new \Exception('Такого пользователя не существует.');
})->only('name', 'email');
// результат
[
    "name" => "Mr. Leon Muller",
    "email" => "maiya57@example.net",
]

Автор: Constantin
Перевод: Demiurge Ash