Eloquent sorgu kapsamları (query scopes), Laravel PHP çerçevesinde kullanılan model sınıfları üzerinde tekrar tekrar kullanılabilen özelleştirilmiş sorgular oluşturmak için kullanılır. Kapsamlar, belirli koşullara göre verileri filtrelemek ve sorgu mantığını model sınıfına yerleştirerek kodun yeniden kullanılabilirliğini ve düzenini iyileştirmek için kullanılabilir.
Genel kullanım amacı, belirli bir model üzerinde sürekli olarak uygulanması gereken sorgu kısıtlamalarını kapsüllemektir. Bu sayede kodun daha temiz, anlaşılır ve sürdürülebilir olması sağlanır. Kapsamlar, model sınıfında tanımlanan özel bir yöntem şeklinde tanımlanır ve bu yöntem bir Builder
örneği alır.
Öncelikle UserScope
adında yeni bir kapsam sınıfı oluşturalım. Bu sınıfı app/Models/Scopes
dizini altında oluşturun ve ardından aşağıdaki kodu kullanarak kapsamı tanımlayın:
php artisan make:scope UserScope
// ...
public function apply(Builder $builder, Model $model): void
{
$builder->where('is_active', 1);
}
// ...
Şimdi User
modeline bu kapsamı eklememiz gerekiyor. Bunu yapmak için, User
modelindeki boot
metodu içerisinde addGlobalScope
yöntemini kullanarak kapsamı ekleyin:
// ...
protected static function boot()
{
parent::boot();
// UserScope kapsamını modele ekler
static::addGlobalScope(new UserScope());
}
// ...
is_active
değerini users
tablosuna eklemek için yeni bir migration dosyası oluşturmalı ve ardından bu migration dosyasında up
ve down
metodlarını tanımlayarak is_active
sütununu ekleyip kaldırmalısınız.
İlk olarak, terminalde aşağıdaki komutu çalıştırarak yeni bir migration dosyası oluşturun:
php artisan make:migration add_is_active_to_users_table --table=users
Bu komut, database/migrations
dizini altında yeni bir migration dosyası oluşturacaktır. Dosya adı, add_is_active_to_users_table
ön ekiyle başlayacak ve zaman damgası içerecektir. Şimdi, bu migration dosyasını düzenleyerek is_active
sütununu ekleyin:
// ...
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('is_active')->default(1); // 0: pasif, 1: aktif
});
}
// ...
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('is_active');
});
}
// ...
Yukarıdaki örnek migration dosyasında, up
metodu, users
tablosuna is_active
adında yeni bir boolean sütun eklemektedir ve varsayılan değeri 0 olarak ayarlamaktadır. down
metodu ise, is_active
sütununu kaldırmaktadır.
Son olarak, terminalde aşağıdaki komutu çalıştırarak migration’ı uygulayın:
php artisan migrate
Bu komut, yeni is_active
sütununu users
tablosuna ekleyecektir.
Bu aşamadan sonra kullanıcıların aktif/pasif durumunu dashboard’da user resource arayüzünde yönetmek için; Nova Switcher eklentisini kullanarak güzel bir arayüz oluşturabilirsiniz.
Not: Durumunu pasif olarak değiştirdiğiniz kullanıcılar, sisteme giriş yapamaz.
Kullanıcılar için yönetim panelinde pasif kullanıcılar için bir model ve resource oluşturarak çöp kutusu mantığında kullanabilirsiniz.
Aşağıda bu senaryoyu uygulamanın adımlarını bulabilirsiniz.
UserPasif
modeli oluşturun:
php artisan make:model UserPasif
UserPasif
modelini oluşturun ve bu modelin User
modeli ile aynı tabloyu kullanmasını sağlayın. Bu modelde global kapsamı uygulamayın.
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\Scopes\UserScope;
use Illuminate\Database\Eloquent\Model;
class UserPasif extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $table = 'users';
}
UserPasif
kaynağını oluşturun:
UserPasif
kaynağı için bir Nova Resource oluşturun ve bu kaynağı User
kaynağı gibi yapılandırın. Ayrıca, bu kaynak için indexQuery
metodunu özelleştirerek, yalnızca pasif kullanıcıların gösterilmesini sağlayın.
php artisan nova:resource UserPasif
// ...
public static function indexQuery(NovaRequest $request, $query)
{
// Yalnızca pasif kullanıcıları gösterir
return $query->where('is_active', 0);
}
// ...