Scope in Model - Laravel

morcosgad

Morcos Gad

Posted on November 13, 2022

Scope in Model - Laravel

I found this wonderful resource https://learn2torials.com/a/laravel8-global-model-scope that takes us on a journey to know Scope. I will present the main points in a quick way, but increase the source and enjoy the article

  • Global Scope

Let's create a new class under app/Scopes/HasActiveScope.php file with following contents

<?php

namespace App\Scopes;

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

class HasActiveScope 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('active', true);
    }
}
Enter fullscreen mode Exit fullscreen mode

you should override the model's booted method and invoke the model's addGlobalScope method. The addGlobalScope method accepts an instance of your scope as its only argument

<?php

namespace App\Models;

use App\Scopes\HasActiveScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        // using seperate scope class
        static::addGlobalScope(new HasActiveScope);

        // you can do the same thing using anonymous function
        // let's add another scope using anonymous function
        static::addGlobalScope('delete', function (Builder $builder) {
            $builder->where('deleted', false);
        });
    }
Enter fullscreen mode Exit fullscreen mode

use global scope

# fetching all active and non-deleted users
$users = User::all();

# above query will result in following sql
select * from `users` where `active` = 1 and `deleted` = 0
Enter fullscreen mode Exit fullscreen mode
  • Remove Scope From Query

you might not want your global filter to apply. For example, if you want to fetch all users weather they are active or not. In that case you can remove your applied scope using following example

# fetch all users weather they are active or not
$users = User::withoutGlobalScope(new HasActiveScope)->all();

# fetch active users weather they are deleted or not
User::withoutGlobalScope('delete')->all();
Enter fullscreen mode Exit fullscreen mode
  • Local Scope

Local scopes are prefixed using Scope keyword. In this case instead of defining global scope you can add local scope in your Laravel model like following

<?php

namespace App\Models;

use App\Scopes\HasActiveScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }

    public function scopeDelete($query)
    {
        return $query->where('delete', 0);
    }
}
Enter fullscreen mode Exit fullscreen mode

use local scope

# apply active local scope to following query
$users = User::active()->orderBy('created_at')->get();

# apply delete local scope to following query
$users = User::delete()->orderBy('created_at')->get();
Enter fullscreen mode Exit fullscreen mode
  • Dynamic Scopes

Sometime you may want to pass additional parameter to your local scope. In that case we can pass dynamic parameter to our local scope and it will act as dynamic scope

<?php

namespace App\Models;

use App\Scopes\HasActiveScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }

    public function scopeDelete($query)
    {
        return $query->where('delete', 0);
    }

    public function scopeWithRole($query, $role)
    {
        return $query->where('role', $role);
    }
}
Enter fullscreen mode Exit fullscreen mode

use dynamic scopes

# find active users with role admin
$users = User::active()->withRole('admin')->all();
Enter fullscreen mode Exit fullscreen mode

I hope you enjoyed the article and I hope you always enjoy the code .

💖 💪 🙅 🚩
morcosgad
Morcos Gad

Posted on November 13, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Laravel Type Casting
laravel Laravel Type Casting

September 27, 2024

Scope in Model - Laravel
laravel Scope in Model - Laravel

November 13, 2022

Laravel Multiple Authentication
laravel Laravel Multiple Authentication

July 25, 2022