Search

Laravel Scopes A Powerful Feature for Query Filtering

  • Share this:
post-title

Hello, today I want to talk about the Laravel Scopes in Laravel. In programming, to write scalable, reusable, and clean code, you need to follow some programming principles.

What is Laravel Scopes ?

Laravel Scopes are a way to encapsulate query constraints into reusable and easy-to-use methods. They provide a convenient method of applying conditions to queries, helping to reduce code duplication and improve code organization.

Types of Laravel Scopes ?

There are two types of Laravel Scopes — global scopes and local scopes.

Global Scopes:

Global scopes are defined within the model itself and are automatically applied to all queries performed on that model. Global scopes are useful when you want to enforce certain conditions globally without explicitly adding them to every query.

Local Scopes:

Local scopes are defined as methods within the model and can be used to apply query constraints on a per-use basis.

STEP 1: Installing Laravel via Composer

You can ignore this step if you already have an application downloaded, or else run the following command to create a brand new Laravel project.

composer create-project laravel/laravel {directory} 11.0 --prefer-dist

STEP 2: Configure Database Connection

In this type of project, we must give precedence to the database connection; generally,  it should be configured before getting started. Incorporate the following code in the.env file with your database details.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

Let’s create a new class (scope) for app/Models/User.php:

Generating Scopes

To create a new global scope in laravel, use the “php artisan make:scope” command. This command will generate the scope and place it in the app/Models/Scopes directory of your application:

php artisan make:scope ActiveUserScope

After generate a class that implements the Illuminate\Database\Eloquent\Scope interface. This interface mandates the implementation of a single method: apply. Within the apply method

<?php
 
namespace App\Models\Scopes;
 
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
 
class ActiveUserScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     */
    public function apply(Builder $builder, Model $model): void
    {
        $builder->where('status', '=',true);
    }
}

Applying Global Scopes

To apply a global scope to a model, override the model’s booted method and call the model’s addGlobalScope method. The addGlobalScope method takes an instance of your scope as its sole argument:

<?php

namespace App\Models;

use App\Models\Scopes\ActiveUserScope;
use Illuminate\Database\Eloquent\Attributes\ScopedBy;

#[ScopedBy([ActiveUserScope::class])]
class User extends Model
{
   //
}

Or, you may manually register the global scope by overriding 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\Models\Scopes\ActiveUserScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * The "booted" method of the model.
    */
   protected static function booted(): void
   {
       static::addGlobalScope(new ActiveUserScope);
   }
}

After adding the scope in the example above to the App\Models\User model, a call to the methods all(), get(), first() etc., you will execute the following SQL query:

select * from `users` where `is_active` = true

Removing Global Scopes

If you would like to remove a global scope for a given query, you may use the withoutGlobalScope method. This method accepts the class name of the global scope as its only argument:

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

If you would like to remove several or even all of the query's global scopes, you may use the withoutGlobalScopes method:

// Remove all of the global scopes...
User::withoutGlobalScopes()->get();
 
If you would like to remove specific global scopes you may use the withoutGlobalScopes method with code: 

// Remove some of the global scopes...
User::withoutGlobalScopes([
    FirstScope::class, SecondScope::class
])->get();

Local Scopes:

Local scopes are defined as methods within the model and can be used to apply query constraints on a per-use basis. 

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
   /**
   * @param Builder $builder
   * @return void
   */
   public function scopeActiveUser(Builder $builder): void
   {
       $builder->where('status', 'true',true);
   }
}

Utilizing a Local Scope

After defining the scope, you can invoke its methods when querying the model. However, it’s important to note that you shouldn’t include the scope prefix when calling the method. 

use App\Models\User;
 
$users = User::activeUser()->get();
select * from `users` where `status` = true

Benefits of Laravel Scopes:

  • Code Reusability
  • Improved Readability
  • Flexibility
About author
Here’s My little description of your attention on Me and My blog. I am here to help you with PHP programming.
View all posts (53)