Скоупы и переиспользуемые запросы
Локальные скоупы
Скоуп — это метод, который добавляет условие к запросу. Имя должно начинаться с 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 вокруг каждого условия.