Получение одной записи в моделях Eloquent в Laravel
В прошлом уроке цепочка запроса
заканчивалась на get -
в ответ приходила коллекция,
даже если в таблице подошла
одна строка. На странице «профиль
пользователя» или «один пост»
коллекция не нужна: ожидают
один объект - или ничего,
если запись не найдена.
Для одной строки вместо get
вызывают first. Метод
мы уже встречали в разделе
построителя запросов
- там он работал с DB::table.
У модели Eloquent принцип тот же:
сначала условие через where,
затем first в конце цепочки.
Важно: first возвращает
не коллекцию, а один объект
модели - или null,
если подходящей строки нет.
К полям обращаются как
$post->title, как после
all в цикле, только
без перебора.
Метод first с условием where
Классический случай - одна запись
по известному id.
Условие задают через where,
результат забирают через first:
<?php
$post = Post::where('id', 1)->first();
dump($post);
?>
В переменной $post -
экземпляр Post
или null. Свойства
строки доступны как поля объекта:
<?php
$post = Post::where('id', 1)->first();
if ($post) {
dump($post->title);
dump($post->text);
}
?>
Проверка if ($post)
нужна, когда запись может
отсутствовать - иначе обращение
к свойствам вызовет ошибку.
Условие по другому полю
first не привязан к id.
Условие может быть на любую колонку -
возраст, email, slug.
Получим пользователя с возрастом
30 лет:
<?php
$user = User::where('age', 30)->first();
dump($user);
?>
Или первого пользователя с заданным email:
<?php
$user = User::where('email', 'test@example.com')->first();
dump($user);
?>
К where можно добавить
ещё фильтры - как в уроке
про конструктор запросов.
first всё равно вернёт
только одну строку.
<?php
$user = User::where('age', 30)
->where('city', 'Moscow')
->first();
dump($user);
?>
Отличие от get
Если условию подходят несколько
строк, get вернёт их все,
а first - только первую
из результата. Порядок без
orderBy не гарантирован,
поэтому для «любого одного
из нескольких» first уместен,
а для точного выбора лучше
уточнить условие или сортировку.
<?php
// все юзеры 30 лет - коллекция
$users = User::where('age', 30)->get();
// один из них - объект или null
$user = User::where('age', 30)->first();
?>
Сравнение с построителем запросов на том же примере:
<?php
$post = DB::table('posts')->where('id', 1)->first();
$post = Post::where('id', 1)->first();
?>
Через DB::table приходит
объект со свойствами полей.
Через модель - экземпляр Post
с теми же данными, но уже
в «обёртке» Eloquent.
Передача в представление
Один объект удобно передать
в Blade целиком - без цикла
foreach, как для списка
из all или get:
<?php
class UserController extends Controller
{
public function show()
{
$user = User::where('age', 30)->first();
return view('user.show', ['user' => $user]);
}
}
?>
В шаблоне проверяют, что пользователь найден, и выводят поля по отдельности:
@if ($user)
<p>{{ $user->name }}</p>
<p>{{ $user->email }}</p>
<p>{{ $user->age }}</p>
@else
<p>Пользователь не найден.</p>
@endif
Когда нужна запись строго
по id, есть отдельный
короткий метод find -
его разберём в следующем уроке.
Практические задачи
Получите юзера с возрастом 30.
Передайте этого юзера в представление. Выведите его данные в отдельных тегах.
Если юзер не найден, выведите в представлении сообщение «не найден».