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

от автора

Итак, узнал сегодня небольшую фитчу 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, реализует этот трюк при регистрации глобального скоупа, для перехвата всех запущенных запросов, при мягком удаление моделей.

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

ссылка на оригинал статьи http://habrahabr.ru/post/259589/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *