Коллекции

Введение

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

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

$users = User::where('is_active', true)->get();

foreach ($users as $user) {
    echo $user->name;
}

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

$users = User::get();

$names = $users->filter(function ($user) {
        return $user->is_active === true;
    })
    ->map(function ($user) {
        return $user->name;
    });

Примеры

Следующие методы вернут объект Коллекции:

$collection = User::all();
$collection = User::where('name', 'Joe')->get();
$collection = User::find(3)->groups;

Конвертация коллекции в JSON или массив

$phpArray = $collection->toArray();

$jsonString = $collection->toJson();

Нахождение первого совпадения

$found = $collection->first(function($model) {
    return $model->color == 'red';
});

Итерация коллекции

$collection->each(function($model) {
    $model->is_cool = true;
});

Проверка ключа

if ($collection->contains(3)) {
    // Коллекция имеет Модель с ID = 3
}

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

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

class User extends Model
{
    /**
     * Create a new Collection instance.
     */
    public function newCollection(array $models = [])
    {
        return new CustomCollection($models);
    }
}

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

use October\Rain\Database\Collection as CollectionBase;

class CustomCollection extends CollectionBase
{
}

Data feed

Data feed позволяют Вам объединять модели классов в одну коллекцию. Это полезно для создания списка данных, в котором используется навигация. Объекты подготавливаются до вызова метода get, после чего они объединяются в коллекцию, которая имеет вид обычного набора данных

Класс DataFeed имитирует модель Active Record и поддерживает методы limit и paginate.

Использование

В следующем примере модели User, Post и Comment будут объединены в одну коллекцию, которая будет содержать 10 записей.

$feed = new October\Rain\Database\DataFeed;
$feed->add('user', new User);
$feed->add('post', Post::where('category_id', 7));

$feed->add('comment', function() {
    $comment = new Comment;
    return $comment->where('approved', true);
});

$results = $feed->limit(10)->get();

Обработка результатов

Метод get вернет объект Collection, который содержит результаты запроса. Записи могут быть дифференцированны при помощи атрибута tag_name, который был установлен в качестве первого параметра при создании модели.

foreach ($results as $result) {

    if ($result->tag_name == 'post')
        echo "New Blog Post: " . $record->title;

    elseif ($result->tag_name == 'comment')
        echo "New Comment: " . $record->content;

    elseif ($result->tag_name == 'user')
        echo "New User: " . $record->name;

}

Сортировка результатов

Результаты могут быть отсортированы по одной колонке таблицы для всех результатов или индивидуально при помощи метода add. Отдельно указывается направление сортировки.

// Ordered by updated_at if it exists, otherwise created_at
$feed->add('user', new User, 'ifnull(updated_at, created_at)');

// Ordered by id
$feed->add('comments', new Comment, 'id');

// Ordered by name (specified default below)
$feed->add('posts', new Post);

// Specifies the default column and the direction
$feed->orderBy('name', 'asc')->get();