Добавление собственных классов и методов в 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" в коллекции.