Global Scope mirip dengan local scope (model scope) yang mana berguna agar membuat scope pada query agar nantinya tidak melakukan pemanggilan query berulang serta membuat kode lebih mudah dibaca sehingga lebih clean. Hal yang membedakan dengan local scope, yaitu global scope tidak dibuat pada model langsung melainkan dibuatkan class tersendiri sehingga kita hanya perlu membuat satu query dan dapat digunakan di berbagai model.
Pada contoh kasus kali ini kita akan menerapkan global scope dengan rule berikut:
- Jika user merupakan role Administrator (id: 2), maka data tidak akan terfilter.
- Jika user bukan merupakan role Administrator (ex: Admin SKPD), maka data akan terfilter dan hanya dapat melihat data dengan `skpd_id` yang sama dengan user
Setup
Pertama kita akan membuat global scope dengan perintah:
php artisan make:scope SkpdFilterScope
Setelah itu, maka dia akan membuatkan kita 1 folder Scopes
yang di dalam nya ada file SkpdFilterScope.php
. Lihat file nya tepat di dalam direktori app/Models/Scopes/SkpdFilterScope.php
. Ingat, bahwa class ini hanya mengandung 1 metode yaitu apply
, jadi jika Anda mencoba untuk membuat 1 lagi metode dibawahnya maka itu akan error. Karena class ini sendiri di implementasikan dengan interface Scope
yang di dalamnya hanya ada 1 metode seperti:
public function apply(Builder $builder, Model $model);
Nah, sekarang Anda bisa masukkan query yang ingin dibuat tepat pada metode apply
itu seperti:
public function apply(Builder $builder, Model $model): void
{
if (!session('employee_id')) {
return;
}
$idColumn = $model->getTable() == 'employees' ? 'id' : 'employee_id';
$builder->where('skpd_id', session('skpd_id'))->whereNot($idColumn, session('employee_id'));
}
kode diatas terdapat beberapa kondisi yaitu:
- jika user tidak memiliki session
employee_id
(bukan akun pegawai/ administrator), maka data tidak akan terfilter.
- jika user memiliki session
employee_id
(akun pegawai/ admin SKPD) maka akan terfilter berdasarkan skpd id
- jika tabel yang ingin difilter adalah tabel employees maka akan dicari berdasarkan kolom
id
, jika bukan maka akan dicari berdasarkan kolom employee_id
. Ini untuk mengecualikan data admin SKPD itu sendiri.
Untuk menerapkan class scope yang telah dibuat ada beberapa cara. berikut caranya:
Default Model Scope
Cara ini membuat global scope yang dibuat akan diterapkan pada model setiap model itu dipanggil, sehingga menjadi default scope. Misal kita ingin menarapkannya pada model Employee
, kita tinggal menambahkan kode berikut pada model:
protected static function booted(): void
{
static::addGlobalScope(new SkpdFilterScope);
}
Functional Scope
Dengan cara ini global scope akan diterapkan hanya ketika kita memanggilnya sehingga lebih modular. misalnya kita ingin menerapkan pada AttendanceController
untuk get data kehadiran pegawai dengan scope tadi:
$attendances = Attendance::applyScopes(SkpdFilterScope::class)->get();