Самый кайф при работе с Laravel — это найти альтернативный способ делать старые и уже наскучившие тебе вещи. Недавно, при работе с Eloquent, я столкнулся с тем, что называют Higher Order Messages (Сообщения высшего порядка). Этот функционал появился в Laravel 5.4.
Higher Order Messages — это причудливый термин, обозначающий механику, когда компьютерная программа разрешает сообщения, содержащие другие сообщения в качестве аргументов/методов. Звучит запутанно? Поверь мне, все не так сложно. Давайте разберемся с этим на примере.
Допустим, у нас есть модель User
связанная с таблицей users
, которая выглядит примерно так:
namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { // пока здесь ничего нет }
Давайте сделаем для неё контроллер. Назовем его UserController
.
namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\User; 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 ] }); } }
Ожидаемо — вышеприведенный код вернет ответ с указанными полями для каждого пользователя. Именно здесь вступают в игру Higher Order Messages, при условии, что вы хотите сделать код более аккуратным.
Используя их, мы можем определить метод (с логикой замыкания map
) прямо в модели…
namespace App; use Illuminate\Database\Eloquent\Model; 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
.
Автор: Amit Merchant
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.