Самый кайф при работе с 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.
