Как стать автором
Обновить

Загрузка моделей, трейтов

Время на прочтение2 мин
Количество просмотров12K
Автор оригинала: Simon Archer
Итак, узнал сегодня небольшую фитчу Laravel/Eloquent, которая практически не описана и лишь вскользь упомянута в документации фреймовика.

Перейдите к TL;DR, если вы просто хотите увидеть эту фичу.

Возможно, вы уже знаете, что можно добавлять статические boot()-методы к Eloquent-модели, которые будут выполнены при ее загрузке. Это можно использовать, например, привязываясь к событиям модели, если это необходимо. Например, вы можете организовать email-уведомление, каждый раз, когда будет создан новый пользователь(неудачный пример), но вы могли бы описать это следующим образом:
    class User extends Eloquent {
        public static function boot()
        {
            parent::boot();
            static::created(function($user) {
                // Send a mailing…
            });
        }
    }

Но что если вы хотите поместить это с trait?

Рассмотрим такой сценарий; необходимо организовать поиск в диапазоне моделей. Конечно, можно создать новый класс SearchableModel, унаследовав его от Eloquent\Model, но хотелось бы написать таким образом, чтобы функционал был легко переносим в другие проекты, не привязываясь к конкретному приложению. Трейт здесь подойдет как-никак лучше, потому что он легко переносим и относительно ненавязчив, подключая который вы получаете дополнительный функционал, который может быть легко переопределен.

Итак, я создал SearchableTrait.
     trait SearchableTrait {
	
         public function search($query)
         {
             // ...
         } 
    }

Довольно просто пока, мы вызываем метод $model->search('query'), возвращающий модели, соответствующие критериям запроса.

Тем не менее, вместо непосредственного поиска по базе данных я планирую использовать сторонний поиск по приложению(если кому интересно, elasticsearch), использующий собственную индексацию, которая требует настройки индекса каждой строки вручную.

Но куда мне вставить этот код?

Я мог бы поместить его в boot()-метод модели, но там он может быть затерт, тем самым нарушая мой поиск и уничтожая любой шанс быть повторно использованным.

TL; DR

Ребята из Laravel явно предусмотрели, каким образом подгружать ваши трейты, определяя специальное метод, как в Eloquent-модели, к примеру:
    trait SearchableTrait {
	
        public function search($query)
        {
            // ...
        }
	
        public static function bootSearchableTrait()
        {
            static::created(function($item){
                // Index the item
             });
        }
    }

Таким образом, здесь присутствует небольшая классическая магия Eloquent. Если у вас есть статический метод в трейте, который называется по принципу boot[NameOfTrait], то он будет выполнен также, как статический boot()-метод модели. Какое удобное место для регистрации событий своей модели.

Пример в документации по Laravel, реализует этот трюк при регистрации глобального скоупа, для перехвата всех запущенных запросов, при мягком удаление моделей.

Конечно же, кроме этой фичи, есть и другие хорошие способы для достижения того же результата, но всегда приятно держать плохо документированные тонкости в своем арсенале, чтобы воспользоваться ими в случае необходимости.
Теги:
Хабы:
+3
Комментарии7

Публикации

Истории

Работа

PHP программист
161 вакансия

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн