Урок 05

Скоупы и переиспользуемые запросы

Локальные скоупы

Скоуп — это метод, который добавляет условие к запросу. Имя должно начинаться с scope:

public function scopePublished($query)
{
    return $query->where('published', true);
}

public function scopeRecent($query)
{
    return $query->orderBy('created_at', 'desc');
}

Использование:

Post::published()->recent()->get();

Скоупы с параметрами

public function scopeOfType($query, string $type)
{
    return $query->where('type', $type);
}
Post::ofType('article')->get();

Глобальные скоупы

Глобальный скоуп применяется ко всем запросам модели автоматически.

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class ActiveScope implements Scope
{
    public function apply(Builder $builder, Model $model): void
    {
        $builder->where('is_active', true);
    }
}

Подключение в модели:

protected static function booted(): void
{
    static::addGlobalScope(new ActiveScope());
}

Отключение глобального скоупа

Post::withoutGlobalScope(ActiveScope::class)->get();
Post::withoutGlobalScopes()->get();

Условные запросы

Метод when добавляет условие, только если значение истинно:

$query = Post::query();

$query->when($request->filled('search'), function ($q) use ($request) {
    $q->where('title', 'like', "%{$request->search}%");
});

$posts = $query->get();

Это чище, чем писать if вокруг каждого условия.