laravel eloquent scope | java php laravel linux mysql sql bootstrap html css query java php laravel linux mysql sql bootstrap html css query: laravel eloquent scope

Sunday, April 12, 2026

laravel eloquent scope

📚 Seri Belajar Laravel Artikel ke-28 dari 50 ⚡ Intermediate

Scope di Eloquent:
Query yang Lebih Bersih
dan Reusable

Lelah nulis kondisi query yang sama berulang-ulang? Saatnya kenalan dengan Eloquent Scope — fitur Laravel yang bikin kode kamu lebih rapi, DRY, dan mudah di-maintain. Dijamin dwell time di sini worth it!

⏱️
Estimasi Baca
8–10 Menit
🎯
Level
Intermediate
📅
Diperbarui
2025
🔗
Seri
50 Artikel Laravel

Pernah nggak kamu nulis ->where('status', 'active') di sepuluh tempat berbeda dalam satu proyek Laravel? Lalu suatu hari requirement berubah jadi 'active AND verified' — dan kamu harus buka satu per satu file buat update query-nya. Menyiksa, kan?

Di seri 50 Artikel Belajar Laravel ini, artikel ke-28 akan membahas solusinya: Eloquent Scope. Fitur ini wajib kamu kuasai setelah memahami autentikasi Laravel Breeze di artikel-artikel sebelumnya. Scope adalah cara elegan Laravel untuk membungkus logika query yang berulang jadi satu method yang bisa dipanggil kapan saja dan di mana saja.

Siap bikin query kamu lebih bersih dari meja makan setelah liburan lebaran? Yuk mulai! 🚀

📐 Formula / Definisi Utama

"Eloquent Scope adalah method di dalam Model yang membungkus kondisi query, sehingga bisa dipanggil secara berantai (chainable) dan digunakan kembali tanpa duplikasi kode."

Ada dua jenis scope: Local Scope (kondisi yang bisa dipanggil secara eksplisit) dan Global Scope (kondisi yang otomatis diterapkan di setiap query model tersebut).

🔍 Apa Itu Eloquent Scope dan Kenapa Kamu Perlu Paham Ini?

Bayangkan kamu punya warung kopi. Setiap pagi kamu selalu mengambil kopi yang sudah dimasak (status = 'ready'), stok di atas 0 (stock > 0), dan tidak kadaluarsa (expired_at > now()). Kalau kamu harus nulis tiga kondisi itu setiap kali butuh daftar kopi siap saji — ribet banget!

Nah, Scope di Eloquent itu seperti kamu punya "menu shortcut": cukup bilang ->available() dan otomatis tiga kondisi tadi langsung teraplikasi. Clean, DRY (Don't Repeat Yourself), dan mudah di-maintain.

Dalam konteks proyek Laravel dengan autentikasi Laravel Breeze, kamu pasti sudah punya model User. Di sinilah Scope paling sering dipraktikkan: menyaring user aktif, user terverifikasi, user dengan role tertentu, dan sebagainya.

🔥
Fakta Menarik

Fitur Local Scope sudah ada sejak Laravel 4.x — salah satu fitur tertua yang masih eksis dan semakin disempurnakan hingga Laravel 11. Artinya, ratusan ribu proyek Laravel di seluruh dunia sudah memanfaatkan ini.

⚙️ Local Scope: Cara Praktis dengan autentikasi Laravel Breeze

Local Scope adalah scope yang kamu definisikan sendiri di model dan dipanggil secara eksplisit di query. Konvensinya: nama method di model diawali kata scope, lalu dipanggil tanpa prefix itu.

📋 Langkah-Langkah Membuat Local Scope
1
Buka Model yang Ingin Ditambahi Scope

Misalnya kita pakai model User.php yang sudah ada di proyek Laravel dengan autentikasi Laravel Breeze. Buka file di app/Models/User.php.

2
Tambahkan Method dengan Prefix "scope"

Tulis method dengan konvensi scopeNamaScope(Builder $query) di dalam class model:

app/Models/User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    // 🔑 Local Scope: hanya user aktif
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('status', 'active');
    }

    // 🔑 Local Scope: hanya email yang terverifikasi
    public function scopeVerified(Builder $query): Builder
    {
        return $query->whereNotNull('email_verified_at');
    }

    // 🔑 Local Scope dengan parameter: filter berdasarkan role
    public function scopeRole(Builder $query, string $role): Builder
    {
        return $query->where('role', $role);
    }
}
3
Panggil Scope di Controller atau Query

Sekarang kamu bisa merantai scope-scope tadi dengan sangat elegan:

app/Http/Controllers/UserController.php
// ✅ Dengan Scope — bersih & readable
$users = User::active()->verified()->get();

// ✅ Scope dengan parameter
$admins = User::active()->role('admin')->get();

// ❌ Tanpa Scope — verbose & mudah error
$users = User::where('status', 'active')
    ->whereNotNull('email_verified_at')
    ->get();
💡
Tips Praktis

Scope bisa dirantai (chained) secara bebas. User::active()->verified()->role('admin')->paginate(20) adalah query yang valid dan elegan. Urutan pemanggilan scope tidak mempengaruhi hasil.

🌐 Global Scope: Kondisi Otomatis di Semua Query

Kalau Local Scope harus dipanggil secara eksplisit, Global Scope bekerja sebaliknya — ia otomatis diterapkan di setiap query yang menggunakan model tersebut. Analoginya seperti filter Instagram yang otomatis aktif: setiap foto yang kamu upload langsung kena filter itu.

Contoh paling populer dari Global Scope di Laravel adalah SoftDeletes — setiap query otomatis mengecualikan record yang sudah dihapus (deleted_at IS NOT NULL). Kamu juga bisa membuat Global Scope sendiri!

app/Models/Scopes/ActiveScope.php
<?php

namespace App\Models\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('status', 'active');
    }
}
app/Models/User.php — Registrasi Global Scope
use App\Models\Scopes\ActiveScope;

class User extends Authenticatable
{
    // Daftarkan Global Scope di method booted()
    protected static function booted(): void
    {
        static::addGlobalScope(new ActiveScope);
    }
}

// Sekarang SEMUA query User otomatis filter status = 'active'
$users = User::all(); // otomatis WHERE status = 'active'

// Ingin bypass Global Scope? Gunakan withoutGlobalScope()
$allUsers = User::withoutGlobalScope(ActiveScope::class)->all();
⚠️
Perhatian!

Global Scope yang terlalu agresif bisa menyebabkan bug tersembunyi di admin panel. Misalnya, jika kamu pasang ActiveScope di model User, maka halaman manajemen user yang seharusnya menampilkan semua user (termasuk yang nonaktif) akan gagal — kecuali kamu sadar untuk memakai withoutGlobalScope().

📊 Perbandingan & Kapan Harus Pakai Scope vs Query Biasa

Kunci menggunakan Scope dengan baik adalah tahu kapan memakainya. Berikut perbandingan lengkapnya:

Aspek Query Biasa Local Scope Global Scope
Reusability ❌ Harus tulis ulang ✅ Bisa dipakai ulang ✅ Otomatis di semua query
Keterbacaan Kode ⚠️ Verbose ✅ Ekspresif & bersih ✅ Transparan di model
Fleksibilitas ✅ Bebas kapan saja ✅ Dipanggil sesuai kebutuhan ⚠️ Perlu bypass manual
Kemudahan Maintenance ❌ Update banyak tempat ✅ Update satu tempat ✅ Update satu tempat
Cocok Untuk Query unik/satu kali pakai Filter yang sering dipakai Aturan bisnis global (soft delete, tenant, dll)
Insight Penting — Best Practice

Kapan pakai Local Scope? Saat kondisi query dipakai di lebih dari 2 tempat berbeda. Nama scope harus mendeskripsikan apa yang dikembalikan, bukan bagaimana cara filternya. Contoh: gunakan scopeActive() bukan scopeWhereStatusActive().

Kapan pakai Global Scope? Untuk aturan bisnis yang tidak boleh dilupakan — seperti multi-tenancy (setiap user hanya bisa lihat data organisasinya sendiri), atau soft delete. Kalau kondisi bersifat opsional, gunakan Local Scope saja.

Pro Insight

Di proyek Laravel dengan autentikasi Laravel Breeze, kamu bisa langsung menambahkan scopeActive() dan scopeVerified() ke model User yang sudah dihasilkan Breeze — tanpa perlu mengubah struktur apapun. Scope hidup berdampingan dengan fitur autentikasi yang ada.

🎛️ Scope Dinamis dan Contoh Nyata di Proyek Laravel

Scope tidak harus statis. Kamu bisa menambahkan parameter untuk membuat scope yang lebih fleksibel. Berikut contoh nyata di proyek e-commerce dengan autentikasi Laravel Breeze:

app/Models/Product.php — Scope Dinamis
class Product extends Model
{
    // Scope dengan parameter: filter harga dalam rentang tertentu
    public function scopePriceBetween(Builder $query, int $min, int $max): Builder
    {
        return $query->whereBetween('price', [$min, $max]);
    }

    // Scope: produk terbaru (bisa custom jumlah hari)
    public function scopeRecent(Builder $query, int $days = 30): Builder
    {
        return $query->where('created_at', '>=', now()->subDays($days));
    }

    // Scope: produk berdasarkan kategori
    public function scopeCategory(Builder $query, string $category): Builder
    {
        return $query->where('category', $category);
    }
}

// Penggunaan — ekspresif & mudah dibaca!
$products = Product::priceBetween(50000, 500000)
    ->recent(7)
    ->category('electronics')
    ->orderBy('price')
    ->paginate(12);
Insight: Readability = Maintainability

Query panjang seperti Product::priceBetween(50000,500000)->recent(7)->category('electronics')->paginate(12) jauh lebih mudah di-review di code review dibanding deretan ->where() yang panjang. Ini bukan sekadar estetika — ini langsung berpengaruh ke kecepatan debugging tim kamu.

Kesimpulan Artikel 28

Scope: Senjata Rahasia Query Eloquent yang Bersih

Di artikel ini kamu telah belajar bahwa:

  • Local Scope membungkus kondisi query berulang menjadi method yang bisa dirantai dan dipanggil sesuka hati
  • Global Scope otomatis menerapkan kondisi di setiap query model — cocok untuk aturan bisnis universal
  • Scope bisa menerima parameter dinamis untuk fleksibilitas maksimal
  • Gunakan autentikasi Laravel Breeze + Scope pada model User untuk manajemen user yang elegan di aplikasi kamu

Scope adalah fondasi menulis Eloquent yang profesional. Di artikel ke-29 kita akan lanjut ke Accessors, Mutators & Casting — cara mengontrol data sebelum masuk dan keluar dari database.

🏷️ Tags Artikel
#Laravel #PHP #Eloquent #EloquentScope #QueryBuilder #LaravelBreeze #Tutorial #BelajarLaravel

No comments:

Post a Comment

saifiahmada.com adalah blog belajar programming Indonesia, membahas lengkap materi bahasa pemrograman: code HTML, CSS, Bootstrap, Desain, PHP, MySQL, coding Java, Query, SQL, dan dunia linux