فرض کنید میخواهید یک محدودیت را روی همه ی کوئری های یک مدل اجرا کنید مثلا یک مدل دارید که فقط روی پست های قدیمی مثلا برای سال 2000 به قبل کار میکند برای اینکار از اسکوپ ها در لاراول استفاده میکنیم
اسکوپ نوع اول اسکوپ های گلوبال می باشند که عملکرد softDeletes در لاراول نیز از همین اسکوپ های گلوبال بهره میگیرد در واقع softDelete روی همه ی کوئری های ما اجرا میشود و فقط ردیف هایی از دیتا بیس را بر میگرداند که ستون deleted_at آن null باشد.
برای تعریف یک scope global جدید باید پوشه Scopes را در پوشه App بسازید سپس در این پوشه یک کلاس به اسم ClassNameScope بسازید دقت کنیم که کامه scope باید در اخر اسم کلاس باشد این کلاس از اینترفیس Illuminate\Database\Eloquent\Scope را implements می کند
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class AncientScope implements Scope { public function apply(Builder $builder, Model $model) { $builder->where('created_at', '<', now()->subYears(2000)); } }
حالا برای apply کردن گلوبال اسکوپ به مدل فقط کافیست در مدل مورد نظر متد booted را باز نویسی کنیم
<?php namespace App\Models; use App\Scopes\AncientScope; use Illuminate\Database\Eloquent\Model; class User extends Model { protected static function booted() { static::addGlobalScope(new AncientScope); } }
اگر میخواستید کوئری ای بزنید که این محدودیت روی ان اعمال نشود فقط کافیست از متد زیر استفاده کنید
User::withoutGlobalScope(AncientScope::class)->get();
Local scope
لوکال اسکوپ ها به شما این امکان را میدهد که برای کوئری هایی که به طور معمول استفاده میکنید یک key انتخاب کنید و هر وقت که از ان key استفاده کنید ان کوئری برای شما اجرا می شود برای مثال
namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { public function scopeOfType($query, $type) { return $query->where('type', $type); } }
حالا در مدل User هرجا بخواهیم میتوانیم مانند زیر از این اسکوپ ها استفاده کنیم
$users = User::ofType('admin')->get();
منبع:
https://laravel.com/docs/9.x/eloquent#global-scopes
نویسنده : حسین غلامیان