Трюки с коллекциями в laravel
Коллекции бывают очень полезными но о них часто забывают. В этой статье я дам несколько советов по их применению.
Вольный перевод. Оригинальная статья http://codebyjeff.com/blog/2015/05/stupid-collection-tricks-in-laravel
Внимание:
Это не страница "лучшей практики", я всего лишь дам несколько советов которые могут быть полезны в нужном месте кода.
Начнём с того, что создадим таблицу people
и пустой класс Eloquent модели с именем Person:
CREATE TABLE `people` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`type` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `people` (`id`, `first_name`, `last_name`, `type`) VALUES
(1, 'Jeff', 'Madsen', 'programmer'),
(2, 'Mickey', 'Mouse', 'engineer'),
(3, 'Daffy', 'Duck', 'critic'),
(4, 'Mighty', 'Mouse', 'programmer');
Трюк #1: find()
Что? find? Да я давно всё знаю о нём. Серьёзно? Проверим?
// Возвратит одну строку как Коллекцию
$collection = App\People::find([1]);
dd($collection);
// Возвратит несколько строк как Коллекции
$collection = App\Person::find([1, 2, 3]);
dd($collection);
С помощью коллекций иногда действительно приятней работать, мы всегда знаем, что возвращается коллекция.
Трюк #2: $collection->where()
Сколько запросов к базе данных вы бы произвели, что бы получить в отдельном массиве всех программистов, инженеров и критиков? Хотите сказать три? Да ни за что в жизни! Один!
// Получаем всех
$collection = App\Person::all();
// фильтруем
$programmers = $collection->where('type', 'programmer');
$critic = $collection->where('type', 'critic');
$engineer = $collection->where('type', 'engineer');
dd($engineer);
Трюк #3: where() & lists()
Возвратит массив с именами всех инженеров
Внимание:
lists в Laravel 5.2 был переименован в pluck
$collection = App\Person::all();
$engineer = $collection->where('type', 'engineer')->lists('first_name'); // ->pluck('first_name') для laravel старше 5.1
dd($engineer);
В WP вы вероятно сделали бы что-то вроде этого:
Внимание:
следующий код написан по памяти и не проверен
// Получаем все метаданные для пользователя с ID = 1
$collection = App\WP_Meta::whereUserId(1)->get();
// Мне нужны значения имени и фамилии
$first_name = $collection->where('meta_key', 'first_name')->lists('value')[0];
$last_name = $collection->where('meta_key', 'last_name')->lists('value')[0];
...любые другие поля, которые вам нужны
Трюк #4: $collection->implode()
Полезный метод (аналогичен php implode), объединит в строку указанный атрибут коллекции с нужным разделителем
$collection = App\Person::all();
$names = $collection->implode('first_name', ',');
echo $names;
Трюк #5: $collection->groupBy()
Мне вас жаль, если вы делали отчёты и не знали этого...
$collection = App\Person::all();
$grouped = $collection->groupBy('type');
dd($grouped);
// Результат
Collection {#152 ▼
#items: array:3 [▼
"programmer" => array:2 [▼
0 => Person {#166 ▶}
1 => Person {#169 ▶}
]
"engineer" => array:1 [▼
0 => Person {#167 ▶}
]
"critic" => array:1 [▼
0 => Person {#168 ▶}
]
]
}
Трюк #6: Объединение
Несколько слов о коде. В примере мы будем использовать одну модель, но на самом деле предполагается это использовать для разных моделей.
use Illuminate\Support\Collection;
...
// Задача в том, что бы объединить результат из различных моделей
$programmers = \App\Person::where('type', 'programmer')->get();
$critic = \App\Person::where('type', 'critic')->get();
$engineer = \App\Person::where('type', 'engineer')->get();
$collection = new Collection;
$all = $collection->merge($programmers)->merge($critic)->merge($engineer);
dd($all);
Теперь предостережения: Будьте осторожны с выбором что делать с результатом. Если вы будете делать циклы при сочетании экземпляров различных классов, то вас могут ожидать сюрпризы, так как некоторые поля данных не всегда могут присутствовать, или могут быть мутаторы в одной из моделей, либо и то и другое вместе. Причём сегодня это может работать нормально, а завтра кто-то придёт и добавит мутатор в модель. По этому прежде всего хорошенько рассчитайте всё.
Надеюсь, что статья Вам помогла!