Добавление собственных классов и методов в Query Билдеры и Коллекции Laravel Моделей
В Laravel есть отличный способ добавить к вашим моделям кастомные методы билдера SQL запросов и коллекций. Этот подход отлично работает для "утоньшения" моделей и написания более чистого кода в ваших контроллерах и сервисах. Благодаря этому, вы можете вынести все scoup* методы в отдельный класс, убрав методы запросов к БД и коллекциям, оставляя лишь бизнес-логику. Потому что, в моделе должна храниться лишь бизнес логика.
Рассматривать будем на примере простой сущности логирования активности пользователей, с которой будем работать по ходу статьи:
use Illuminate\Database\Eloquent\Model;
class Activity extends Model
{
protected $table = 'activity_logs';
protected $fillable = [
'type',
'status',
'subject',
'properties',
'user_id'
];
protected $casts = [
'properties' => 'json',
];
}
Создаём кастомный класс Query Builder-а
Создадим новый класс, унаследовавшись от базового класса Eloquent - Builder.
use Illuminate\Database\Eloquent\Builder;
class ActivityQueryBuilder extends Builder
{
// метод поиска по типу
public function byType(string $type): self
{
$this->where('type', $type);
return $this;
}
// метод поиска по статусу
public function byStatus(string $status): self
{
$this->where('status', $status);
return $this;
}
// метод поиска по идентификатору пользователя
public function byUserId(string $id): self
{
$this->where('user_id', $id);
return $this;
}
}
Добавляем кастомный Билдер в Модель
Для того, чтобы определить свой собственный Query Builder в моделе Laravel, нам нужно добавить метод newEloquentBuilder. В котором нужно инициализировать экземпляр вашего кастомного билдера.
class Activity extends Model
{
// ...
public function newEloquentBuilder($query): ActivityQueryBuilder
{
return new ActivityQueryBuilder($query);
}
}
Создаём кастомный класс коллекции Модели
Создадим новый класс, унаследовавшись от базового класса Eloquent коллекции - Collection.
use Illuminate\Database\Eloquent\Collection;
class ActivityCollection extends Collection
{
// метод коллекции - фильтрация по статусу
public function onlySuccess(): self
{
$this->where('status', 'success');
return $this;
}
}
Добавляем кастомный класс коллекции в Модель
Для того, чтобы добавить свой собственный класс коллекции в модель Laravel, нам нужно добавить метод newCollection. В котором необходимо инициализировать экземпляр класса нашей кастомной коллекции.
use Illuminate\Database\Eloquent\Collection;
class ActivityCollection extends Collection
{
public function onlySuccess(): self
{
$this->where('status', 'success');
return $this;
}
}
Примечание: несмотря на то, что функция
where
в коллекции будет делать то же самое, что и в билдере, лучше делать как можно больше в запросах к базе данных (Query Builder). Функция "where" в запросе к базе данных будет быстрее, чем "where" в коллекции.