Tech Verse Logo
Enable dark mode
Clean, Reusable Query Logic the Right Way: Laravel Global Scopes & Local Scopes

Clean, Reusable Query Logic the Right Way: Laravel Global Scopes & Local Scopes

Tech Verse Daily

Tech Verse Daily

4 min read

As Laravel applications grow, database queries tend to become repetitive and inconsistent. Conditions like is_active = true, deleted_at IS NULL, or tenant_id = ? start appearing everywhere.

Laravel solves this elegantly with Eloquent Scopes.

In this article, we’ll break down Global Scopes and Local (Custom) Scopes, explain when to use each, and demonstrate production-ready implementations following Laravel’s latest best practices.

What Is an Eloquent Scope?

An Eloquent scope is a way to encapsulate common query constraints inside your model so they can be reused, composed, and maintained centrally.

Laravel provides two types:

  1. Global Scopes – Automatically applied to every query

  2. Local Scopes – Explicitly applied when needed

1. Global Scopes

What Is a Global Scope?

A global scope automatically adds constraints to every query executed against a model.

Typical use cases include:

  • Soft deletes

  • Multi-tenancy

  • Active / published records

  • Data visibility rules

Creating a Global Scope (Class-Based)

Step 1: Create the Scope Class

php artisan make:scope ActiveScope

Step 2: Implement the Scope

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('is_active', true);
    }
}

Step 3: Register the Scope on the Model

use App\Models\Scopes\ActiveScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected static function booted(): void
    {
        static::addGlobalScope(new ActiveScope);
    }
}

How It Works

Now, every query automatically includes:

WHERE is_active = true
User::all();        // Only active users
User::find(1);     // Only if active
User::count();     // Only active

No repetition. No mistakes.

Temporarily Disabling a Global Scope

Laravel allows precise control when you need it.

Disable a Specific Scope

User::withoutGlobalScope(ActiveScope::class)->get();

Disable All Global Scopes

User::withoutGlobalScopes()->get();

This is critical for admin panels, background jobs, or audits.

Anonymous Global Scopes (Quick Use)

For simple rules, Laravel allows inline scopes.

protected static function booted(): void
{
    static::addGlobalScope('published', function (Builder $builder) {
        $builder->where('published_at', '<=', now());
    });
}

Use this only when the logic is small and model-specific.

2. Local (Custom) Scopes

What Is a Local Scope?

A local scope is applied only when you explicitly call it.

They’re ideal for:

  • Reusable filters

  • Query composition

  • Readable fluent APIs

Creating a Local Scope

Local scopes are simply model methods prefixed with scope.

Example: scopeActive()

use Illuminate\Database\Eloquent\Builder;

class User extends Model
{
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }
}

Using the Local Scope

User::active()->get();
User::active()->where('role', 'admin')->get();

Laravel removes the scope prefix automatically.

Local Scope with Parameters

Example: scopeRole($role)

public function scopeRole(Builder $query, string $role): Builder
{
    return $query->where('role', $role);
}

Usage

User::role('manager')->get();
User::active()->role('admin')->get();

This makes queries expressive and composable.

Combining Global & Local Scopes

User::active()
    ->role('editor')
    ->latest()
    ->paginate(20);

✔ Global scope ensures visibility rules
✔ Local scopes handle business filters

This is the ideal architecture for scalable apps.

Removing Global Scope Inside a Local Scope

Sometimes you want a local scope that bypasses a global rule.

public function scopeWithInactive(Builder $query): Builder
{
    return $query->withoutGlobalScope(ActiveScope::class);
}

Usage:

User::withInactive()->get();

Best Practices (From Real Projects)

✔ Use global scopes for mandatory constraints
✔ Use local scopes for optional filters
✔ Prefer class-based global scopes
✔ Keep scopes query-only (no side effects)
✔ Name scopes clearly and intentionally

When NOT to Use Scopes

❌ Complex business workflows
❌ Authorization decisions
❌ Cross-model orchestration

Scopes are for query constraints, not domain logic.

Final Thoughts

Eloquent scopes are one of Laravel’s most elegant features. When used properly, they:

  • Eliminate query duplication

  • Enforce consistency

  • Improve readability

  • Scale naturally with your application

If you see the same where() clause repeated more than twice, it’s time for a scope.

    Latest Posts

    View All

    Introducing the Laravel AI SDK — Build Smarter Apps with AI

    Introducing the Laravel AI SDK — Build Smarter Apps with AI

    Laravel AI SDK: Building AI-Powered Applications the Laravel Way

    Laravel AI SDK: Building AI-Powered Applications the Laravel Way

    Getting Started with Mago – The Fastest PHP Tooling Chain

    Getting Started with Mago – The Fastest PHP Tooling Chain

    Best Stack Recommendations for Laravel Projects (Battle-Tested in Production)

    Best Stack Recommendations for Laravel Projects (Battle-Tested in Production)

    Laravel + React Authentication the Right Way: Sanctum, JWT, or Passport?

    Laravel + React Authentication the Right Way: Sanctum, JWT, or Passport?

    Laravel PDF Generator: Spatie Laravel PDF vs Laravel DomPDF (In-Depth Comparison)

    Laravel PDF Generator: Spatie Laravel PDF vs Laravel DomPDF (In-Depth Comparison)

    how to systematically optimize Laravel databases in production

    how to systematically optimize Laravel databases in production

    Optimize Images in Laravel with Intervention Image

    Optimize Images in Laravel with Intervention Image

    Common Security Mistakes in Laravel Apps and How to Fix Them Properly

    Common Security Mistakes in Laravel Apps and How to Fix Them Properly

    Clean, Reusable Query Logic the Right Way: Laravel Global Scopes & Local Scopes

    Clean, Reusable Query Logic the Right Way: Laravel Global Scopes & Local Scopes