1. Eloquent ORM
  2. Eloquent: Коллекции

Присоединяйся к нашему Telegram сообществу @webblend!

Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.

Введение

Все методы Eloquent, возвращающие более одной модели, вернут экземпляры класса Illuminate\Database\Eloquent\Collection, включая результаты, полученные с использованием метода get или доступ к отношениям. Объект коллекции Eloquent расширяет базовую коллекцию Laravel, поэтому он естественным образом наследует десятки методов, используемых для гибкой работы с основным массивом моделей Eloquent. Обязательно ознакомьтесь с документацией по коллекциям Laravel, чтобы узнать больше о этих полезных методах!

Все коллекции также служат итераторами, позволяя вам перебирать их так, как если бы они были простыми массивами PHP:

use App\Models\User;
 
$users = User::where('active', 1)->get();
 
foreach ($users as $user) {
echo $user->name;
}

Однако, как было упомянуто ранее, коллекции гораздо мощнее массивов и предоставляют различные операции map / reduce, которые можно объединять с использованием интуитивно понятного интерфейса. Например, мы можем удалить все неактивные модели, а затем собрать имена для каждого оставшегося пользователя:

$names = User::all()->reject(function (User $user) {
return $user->active === false;
})->map(function (User $user) {
return $user->name;
});

Преобразование коллекции Eloquent

Хотя большинство методов коллекций Eloquent возвращают новый экземпляр коллекции Eloquent, методы collapse, flatten, flip, keys, pluck и zip возвращают экземпляр базовой коллекции. Точно так же, если операция map возвращает коллекцию, которая не содержит моделей Eloquent, она будет преобразована в экземпляр базовой коллекции.

Доступные методы

Все коллекции Eloquent расширяют базовый класс коллекций Laravel; следовательно, они наследуют все мощные методы, предоставленные базовым классом коллекций.

Кроме того, класс Illuminate\Database\Eloquent\Collection предоставляет надмножество методов для управления коллекциями ваших моделей. Большинство методов возвращают экземпляры Illuminate\Database\Eloquent\Collection; однако некоторые методы, такие как modelKeys, возвращают экземпляр Illuminate\Support\Collection.

append($attributes)

Метод append может быть использован для указания того, что атрибут должен быть добавлен к каждой модели в коллекции. Этот метод принимает массив атрибутов или отдельный атрибут:

$users->append('team');
 
$users->append(['team', 'is_admin']);

contains($key, $operator = null, $value = null)

Метод contains можно использовать для определения того, содержится ли заданный экземпляр модели в коллекции. Этот метод принимает первичный ключ или экземпляр модели:

$users->contains(1);
 
$users->contains(User::find(1));

diff($items)

Метод diff возвращает все модели, которые отсутствуют в данной коллекции:

use App\Models\User;
 
$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());

except($keys)

Метод except возвращает все модели, у которых нет указанных первичных ключей:

$users = $users->except([1, 2, 3]);

find($key)

Метод find возвращает модель с первичным ключом, соответствующим указанному ключу. Если $key - это экземпляр модели, find попытается вернуть модель с соответствующим первичным ключом. Если $key - это массив ключей, find вернет все модели, у которых первичный ключ в указанном массиве:

$users = User::all();
 
$user = $users->find(1);

fresh($with = [])

Метод fresh извлекает свежий экземпляр каждой модели из коллекции из базы данных. Кроме того, будут жадно загружены указанные отношения:

$users = $users->fresh();
 
$users = $users->fresh('comments');

intersect($items)

Метод intersect возвращает все модели, которые также присутствуют в данной коллекции:

use App\Models\User;
 
$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());

load($relations)

Метод load жадно загружает указанные отношения для всех моделей в коллекции:

$users->load(['comments', 'posts']);
 
$users->load('comments.author');
 
$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);

loadMissing($relations)

Метод loadMissing жадно загружает указанные отношения для всех моделей в коллекции, если отношения еще не загружены:

$users->loadMissing(['comments', 'posts']);
 
$users->loadMissing('comments.author');
 
$users->loadMissing(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);

modelKeys()

Метод modelKeys возвращает первичные ключи для всех моделей в коллекции:

$users->modelKeys();
 
// [1, 2, 3, 4, 5]

makeVisible($attributes)

Метод makeVisible делает видимыми атрибуты, которые обычно "скрыты" на каждой модели в коллекции:

$users = $users->makeVisible(['address', 'phone_number']);

makeHidden($attributes)

Метод makeHidden скрывает атрибуты, которые обычно "видимы" на каждой модели в коллекции:

$users = $users->makeHidden(['address', 'phone_number']);

only($keys)

Метод only возвращает все модели, которые имеют указанные первичные ключи:

$users = $users->only([1, 2, 3]);

setVisible($attributes)

Метод setVisible временно переопределяет все видимые атрибуты на каждой модели в коллекции:

$users = $users->setVisible(['id', 'name']);

setHidden($attributes)

Метод setHidden временно переопределяет все скрытые атрибуты на каждой модели в коллекции:

$users = $users->setHidden(['email', 'password', 'remember_token']);

toQuery()

Метод toQuery возвращает экземпляр построителя запросов Eloquent с ограничением whereIn на первичных ключах модели коллекции:

use App\Models\User;
 
$users = User::where('status', 'VIP')->get();
 
$users->toQuery()->update([
'status' => 'Administrator',
]);

unique($key = null, $strict = false)

Метод unique возвращает все уникальные модели в коллекции. Любые модели того же типа с тем же первичным ключом, что и другая модель в коллекции, будут удалены:

$users = $users->unique();

Пользовательские коллекции

Если вы хотите использовать объект Collection по умолчанию при взаимодействии с определенной моделью, вы можете определить метод newCollection в своей модели:

<?php
 
namespace App\Models;
 
use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Создает новый экземпляр коллекции Eloquent.
*
* @param array<int, \Illuminate\Database\Eloquent\Model> $models
* @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>
*/
public function newCollection(array $models = []): Collection
{
return new UserCollection($models);
}
}

После того как вы определили метод newCollection, вы получите экземпляр вашей пользовательской коллекции всякий раз, когда Eloquent обычно вернул бы экземпляр Illuminate\Database\Eloquent\Collection. Если вы хотите использовать пользовательскую коллекцию для каждой модели в вашем приложении, вы должны определить метод newCollection в базовом классе модели, который расширяется всеми моделями вашего приложения.