Квест → Как хакнуть форму
Прошли: 77
В Laravel начиная с версии 5.5.29 можно группировать коллекции по нескольким критериям. Давайте посмотрим, что это означает и как это работает.

Итак, эта статья о новой функциональности в фреймворке Laravel. Но прежде чем мы посмотрим как она работает сейчас, давайте посмотрим как она работала раньше. Метод groupBy является методом класса Collection. Для наших примеров я создам немного данных, с которыми мы будем работать. Students будет фабрикой состояний для передаваемого класса User.
// Default user factory which comes with Laravel
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
// Our new students state
$factory->state(App\User::class, 'students', function (Faker $faker) {
return [
'skilllevel' => collect(['beginner', 'intermediate', 'professional'])->random(),
'teacher' => collect(['Peter', 'Markus', 'Chris'])->random(),
];
});
Добавленное состояние будет генерить для нас данные пользователей. У нас есть новые поля skilllevel и teacher. Для наших примеров мы будем использовать простой роутинг с обычным callback'ом. Таким образом, мы можем быстро и легко вернуть результат в браузер.
Route::get('/', function () {
return $students = factory(User::class)
->times(3)
->states('students')
->make();
});
Примечание: мы используйте метод make вместо метода create, потому что у нас нет базы данных.
Этот код "накастует" нам тестовых данных, которые будут выглядит примерно так:
[
{
"name": "Jakayla Leffler",
"email": "ocie70@example.com",
"skilllevel": "professional",
"teacher": "Peter"
},
{
"name": "Gustave Cummings II",
"email": "crona.alexandrea@example.net",
"skilllevel": "intermediate",
"teacher": "Markus"
},
{
"name": "Ms. Ethelyn Bergnaum MD",
"email": "deckow.kelvin@example.net",
"skilllevel": "beginner",
"teacher": "Peter"
}
]
Я сказал "будут выглядит примерно так", потому что мы используем пакет Faker в нашей фабрике. Поэтому каждый результат будет выглядеть по-разному в силу того, что он генерирует случайные данные.
Далее, давайте используем метод groupBy, чтобы сгруппировать наши данные по skilllevel:
return $students->groupBy('skilllevel');
Вы увидите новые ключи для skilllevel в нашем результате:
{
"professional": [
{
"name": "Jacquelyn Kilback",
"email": "christopher55@example.net",
"skilllevel": "professional",
"teacher": "Chris"
}
],
"beginner": [
{
"name": "Miss Ophelia Ryan Jr.",
"email": "pollich.tristin@example.net",
"skilllevel": "beginner",
"teacher": "Chris"
},
{
"name": "Furman Hahn",
"email": "blowe@example.net",
"skilllevel": "beginner",
"teacher": "Markus"
}
]
}
Пока здесь нет ничего действительно нового. Так что же это за новая функция, о которой я говорил? Patrizio T. сделал pull-запрос, так что теперь вы можете группировать коллекции на нескольких уровнях. Чтобы лучше понять, что это значит, давайте взглянем на пример:
return $students->groupBy(['skilllevel','teacher']);
Вместо строки, мы передаем массив, чтобы задать несколько уровней. Сначала коллекция students должна быть сгруппирована по skilllevel, а затем по полю teacher. Итак, вот что мы получили:
{
"intermediate": {
"Peter": [
{
"name": "Jana McClure III",
"email": "oliver.pagac@example.com",
"skilllevel": "intermediate",
"teacher": "Peter"
}
],
"Chris": [
{
"name": "Rosemarie Barrows",
"email": "epurdy@example.com",
"skilllevel": "intermediate",
"teacher": "Chris"
}
]
},
"professional": {
"Markus": [
{
"name": "Katrine Streich",
"email": "carlee.koepp@example.com",
"skilllevel": "professional",
"teacher": "Markus"
}
]
}
}
Эта группировка может быть полезна, когда вы хотите отобразить или сравнить данные. В этом примере только Маркус имеет профессионального студента. Может быть он является лучшим учителем?
Это не имеет смысла для нашего примера, но мы также могли бы группировать студентов по их имени и адресу электронной почты:
return $students->groupBy(['skilllevel','teacher', 'name', 'email']);
Получится "немного" сумасшедшая вложенная структура, но это возможно
:
{
"professional": {
"Peter": {
"Mrs. Ella McClure": {
"forest.bernier@example.com": [
{
"name": "Mrs. Ella McClure",
"email": "forest.bernier@example.com",
"skilllevel": "professional",
"teacher": "Peter"
}
]
}
},
"Chris": {
"Miss Assunta Predovic PhD": {
"amari.klocko@example.com": [
{
"name": "Miss Assunta Predovic PhD",
"email": "amari.klocko@example.com",
"skilllevel": "professional",
"teacher": "Chris"
}
]
}
}
},
"intermediate": {
"Markus": {
"Keshawn Crona DVM": {
"vkilback@example.org": [
{
"name": "Keshawn Crona DVM",
"email": "vkilback@example.org",
"skilllevel": "intermediate",
"teacher": "Markus"
}
]
}
}
}
}
Мне нравится, как теперь просто группировать по нескольким значениям. Синтаксис вполне "прямой", да и работает отлично. Если у вас есть другие хорошие примеры из реальной жизни, делитесь в комментах.