2 simple steps to create Laravel Global Scope in Eloquent Model

What is Global Scope?

Laravel Global Scope is a methodology that does not have to reflect the same query every time we get data from the controller in Laravel 6,7,8 and 9.

I think you already know and have the opportunity to work on soft-delete(where Laravel gets only not deleted items instead of getting all the records from the database) If so, it’s very similar, you can learn it very easily and use it in your project.

Step 1 – Create Global Scopes

First, we need to create a folder under the app folder called Scopes, which will be the app/Scopes. Once you have created a folder, manually create a class file with your custom name.

For instance, StatusScope.php

Code

<?php
  
namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class StatusScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {   
        $builder->where('status', 1);
    }
}

Step 2 – Use Global Scopes

So, when you create a global scope and write some logic in it, we have to use that scope in our model.

<?php
 
namespace App\Models;
 
use App\Scopes\StatusScope;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'avatar'
        'status'
    ];


    protected static function boot()
    {
        parent::boot();
  
        static::addGlobalScope(new StatusScope);
    }
}

Checking in Controller

If you followed steps # 1 and # 2 correctly you would not have to do anything further. The following code will only return the active(status=1) data.

<?php

namespace Modules\UserManagement\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {
        $users =  User::get(); // you will get only active data and you don't have to do any other where condition here!
        dd($users);
    }
}

Removing or excepting Global Scopes

To get all the data without any restrictions, we have a default Laravel method called withoutGlobalScope()

<?php

namespace Modules\UserManagement\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;
use App\Scopes\StatusScope;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {
        $users =  User:: withoutGlobalScope(StatusScope::class)->get(); // When you use withoutGlobalScope method you'll get all data without any condition!
        dd($users);
    }
}

I hope you found this helpful and if you have any doubts about this please ask me in the comment section below.

For more info see the official documentation here

Cheers!