Вот! Сила… макросов!
Как я уже писал ранее, возможности макросов в Laravel довольно велики, поскольку они позволяют расширять класс во время выполнения с помощью ваших собственных методов. Вы можете добавить полезные методы, которые могут преобразовывать подробный код в выразительные однострочники, которые имеют смысл. Один из них выходит из коробки - это проверка запроса:
public function (Request $request) { $request->validate([ 'email' => 'required|unique:users', ]); // ... }
В список классов, реализующих свойство Macroable, которое включает макросы в классе, входят Query Builder и Eloquent Builder. Оба они используются для выполнения запросов непосредственно к базе данных.
Одна из вещей, которые я постоянно делаю, когда мне нужны дорогие вычисления SQL, - это сохранять результат в кэше, что сильно раздувает код:
$votes = 100; $users = Cache::remember('users', 60, function () use ($votes) { return Users::has('comments') ->where('votes', '>', $votes) ->get(); });
Было бы неплохо сделать что-то одной строчкой вместо того, чтобы угадывать, что, черт возьми, я написал?
Конечно!
План, класс и макрос
Я хочу запомнить результаты, используя этот простой синтаксис; вот что я хочу написать в своем приложении:
$results = User::where('something')->remember(60)->get();
Чтобы это сработало, недостаточно добавить метод remember()
в качестве макроса в построитель запросов. Если мы сделаем только это, используя другой другой метод, например get()
(или любой другой метод получения), он вернет результат запроса, минуя любую логику запоминания.
Другими словами: кеш и результат запроса не связаны.
Итак, я закончил создание очень простого пакета, следуя диаграмме ниже. Существует крошечный класс, который после вызова remember()
становится промежуточным звеном между Builder и Cache.
Чтобы лучше объяснить это, когда вы используете метод remember()
, экземпляр Eloquent или Query Builder будет инкапсулирован внутри класса, который будет передавать все ваши методы в Builder ... кроме случаев, когда Builder возвращает результат базы данных - в основном все, кроме самого экземпляра Builder .
Это очень хороший способ делать дорогостоящие вызовы базы данных без использования подробной логики для использования замыканий. Вернемся к нашему первому примеру:
$votes = 100; $users = Cache::remember('users', 60, function () use ($votes) { return Users::has('comments') ->where('votes', '>', $votes) ->get(); });
Хорошо, мы знаем, что используем кеш. Замыкание находится внутри логики кеширования, которая фактически вызывает базу данных при импорте переменной извне. Теперь сравните это с этой выразительной строкой:
$users = Users::has('comments')->where('votes', '>', $votes) ->remember() ->get();
Хорошая часть? Ключ кеша обрабатывается автоматически. По сути, он хеширует SQL-запрос запроса вместе с привязками, делая каждый оператор уникальным. Другими словами, логика может быть такой же, но если вы измените такую переменную, как количество голосов, со 100 на 99, хеш будет другим, и результат будет выполнен и сохранен в кеш-памяти.
Вот и все. Попробуй и скажи мне, что ты думаешь.