Рефакторинг красноречивых запросов с использованием сообщений более высокого порядка в Laravel


Лучшая вещь в работе с Laravel – это найти альтернативный способ делать одни и те же старые скучные вещи время от времени. Я наткнулся на то, что называется «Сообщения высшего порядка» во время работы с Eloquent недавно. Эта функция была в Laravel с версии v5.4.

Сообщения более высокого порядка – это причудливый термин, данный механизму, в котором компьютерная программа допускает сообщения, содержащие другие сообщения в качестве аргументов / методов. Звучит запутанно? Поверь мне, это не так. Давайте разберемся в этом на примере.

Итак, допустим, мы User модель, связанная с таблицей users который выглядит примерно так:



namespace App;

use IlluminateDatabaseEloquentModel;

class User extends Model 
{
    // nothing here as of now
}

Теперь давайте попробуем использовать User модель в контроллер. Давайте назовем это UserController,



namespace AppHttpControllers;

use AppHttpControllersController;
use AppUser;

class UserController extends Controller
{
    public function index()
    {
        return User::where('active', 1);
    }
}

Здесь нет ничего необычного. index Метод контроллера вернет всех активных пользователей в виде массива json. Но проблема здесь в том, что он вернет все поля users стол. Если мы хотим вернуть определенные поля с пользовательскими ключами, мы можем сделать это так.



class UserController extends Controller
{
    public function index()
    {
        return User::where('active', 1)
            ->map(function($user) {
                return (
                    'user_id' => $user->id,
                    'name' => $user->name
                    'title' => $user->title
                )
            });
    }
}

Как и следовало ожидать, приведенное выше сводит ответ к ответу, просто возвращая указанные поля для каждого пользователя. Именно здесь вступают в игру «Сообщения высшего порядка», если вы хотите сделать приведенный выше код немного более аккуратным.

Используя сообщения более высокого порядка, мы можем определить метод (с логикой mapЗакрытие) прямо в модель …



namespace App;

use IlluminateDatabaseEloquentModel;

class User extends Model 
{
    public function transform()
    {
        return (
            'user_id' => $this->id,
            'name' => $this->name,
            'title' => $this->title
        );
    }
}

… И «передать» его map Метод в запросе Eloquent, как показано ниже.



class UserController extends Controller
{
    public function index()
    {
        return User::where('active', 1)
            ->map->transform();
    }
}

Выше, так же, как когда мы используем анонимную функцию в map, Теперь вы можете напрямую передать метод реализации transform из User модель для map, Как вы можете видеть, это может пригодиться, если вы хотите реорганизовать запрос и помогает поддерживать чистоту ваших контроллеров (или фабрик).

Вот все методы сбора, которые поддерживают сообщения более высокого порядка: average, avg, contains, each, every, filter, first, flatMap, map, partition, reject, sortBy, sortByDesc, а также sum,