How to Use Query Scopes in Laravel 7

Hey Artisan

in this tutorial i would like to share example of how to use laravel eloquent scope. i will show you how to create laravel 7 scope eloquent model, and how it will easy for you.

If you don't know how to use eloquent scope in laravel, then this tutorial is for you. Hope you will enjoy this laravel query scope tutorial. 

i will guide you to create use scope in laravel. You can easily use dynamic query scope in laravel 7 application. Let's start laravel scope tutorial.

laravel-scope-with-parameter

Local and global scopes in Eloquent allow you to define prebuilt “scopes” (filters) that you can use either every time a model is queried (“global”) or every time you query it with a particular method chain (“local”).

 

Read also : How to Create and Use Query Scope in Laravel Eloquent

Local scopes

Local scopes are the simplest to understand. Let’s take this example:

$activeVips = Contact::where('vip', true)->where('trial', false)->get();

 

First of all, if we write this combination of query methods over and over, it will get tedious.

But additionally, the knowledge of how to define someone being an “activeVIP” is now spread around our application. We want to centralize that knowledge. What if we could just write this?

$activeVips = Contact::ActiveVips()->get();

 

We can—it’s called a local scope. And it’s easy to define on the Contact class:

class Contact
{
  public function scopeActiveVips($query) {
   return $query->where('vip', true)->where('trial', false);
 }
}

 

To define a local scope, we add a method to the Eloquent class that begins with “scope” and then contains the title-cased version of the scope name.

This method is passed a query builder and needs to return a query builder, but of course you can modify the query before returning—that’s the whole point.

 

You can also define scopes that accept parameters:

 class Contact
    {
        public function scopeStatus($query, $status)
        {
            return $query->where('status', $status);
        }
    }

 

And you use them in the same way, just passing the parameter to the scope:

$friends = Contact::Status('friend')->get();

 

Global scopes

Remember how we talked about soft deletes only working if you scope every query on the model to ignore the soft-deleted items? That’s a global scope. And we can define our own global scopes, which will be applied on every query made from a given model.

There are two ways to define a global scope: using a closure or using an entire class. In each, you’ll register the defined scope in the model’s boot() method. Let’s start with the closure method, illustrated in below example.

 

Adding a global scope using a closure

 class Contact extends Model
    {
        protected static function boot()
        {
            parent::boot();
            static::addGlobalScope('active', function (Builder $builder) {
                $builder->where('active', true);
            });
        }
    }

 

That’s it. We just added a global scope, named active, and every query on this model will be scoped to only rows with active set to true.

Creating a global scope class

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

    class ActiveScope implements Scope
    {
        public function apply(Builder $builder, Model $model)
        {
            return $builder->where('active', true);
        }
    }

 

To apply this scope to a model, once again override the parent’s boot() method and call addGlobalScope() on the class using static, as shown in below example

Applying a class-based global scope

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

    class Contact extends Model
    {
        protected static function boot()
        {
            parent::boot();
            static::addGlobalScope(new ActiveScope);
        }
    }

 

Removing global scopes

There are three ways to remove a global scope, and all three use the withoutGlobalScope() or withoutGlobalScopes() methods.

If you’re removing a closure-based scope, the first parameter of that scope’s addGlobalScope() registration will be the key you used to enable it:

$allContacts = Contact::withoutGlobalScope('active')->get();

 

If you’re removing a single class-based global scope, you can pass the class name to withoutGlobalScope() or withoutGlobalScopes():

Contact::withoutGlobalScope(ActiveScope::class)->get();
Contact::withoutGlobalScopes([ActiveScope::class, VipScope::class])->get();

 

Or, you can just disable all global scopes for a query:

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

 

Hope you have enjoyed this tutorial.