What is a scope for in Laravel?

2

I saw in the documentation of Laravel an explanation about the use of Eloquent. There I saw a part where you talk about Local and Global Scopes .

As I do not speak much English, I had some doubts about using it.

  • What are these methods where we define the scope prefix in models?

  • What is the difference between Local and Global scope?

Documentation example (local scope):

class User extends Model
{
    /**
     * Scope a query to only include popular users.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }
}

Documentation example (global scope):

class User extends Model
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('age', function(Builder $builder) {
            $builder->where('age', '>', 200);
        });
    }
}
    
asked by anonymous 24.08.2016 / 15:25

1 answer

3
  • What are these methods where we define the scope prefix in models ?

It is intended to facilitate query routines in your model (Eloquent) , bringing pre-query functionality to SQL , thus helping in the development and standardization of queries. It is divided into Global Scope or Local Scope .

  • What is the difference between Location and Global scope?

Global Scope limits or restricts your model to pre-filter (where, order by) on all the SQL queries for a particular model (Eloquent) . It would be a standardization for this model that in the execution of queries have this filter. A clear example is the deletion of a particular record where the determinant is a date with the value null the query brings the record, other than null the record does not appear, following the logic of soft-deleting .

Example:

namespace App;    
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;    
class Cliente extends Model
{
    use SoftDeletes;

    protected $dates = ['deleted_at'];
}

In the above case if you code Cliente::all() , it will bring up the list of all clients that were not deleted, because Global Scope of traits SoftDeletes has a restrictive and global filter for all queries ( select * from clientes where deleted_at is null ). If you happen to want to bring all records, including those excluded, do the Cliente::withTrashed()->get() command, which is an elegant way to circumvent this Global Scope . A radical way to eliminate all Global Scope would be like Cliente::withoutGlobalScopes()->get() .

Already in Local Scope is a prepared filter, or shortcut, that is only executed by calling the method, being different from the Global Scope that is always called automatically and transparently. It has the same characteristics, but the form of invocation is what differs.

Example:

namespace App;    
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;    
class Cliente extends Model
{
    use SoftDeletes;

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

    protected $dates = ['deleted_at'];

}

There is a model customer that I set a filter where scopeStatus , but I need to invoke it so that it starts running and the query receives more of this filter.

Cliente::status()->get(); 
//SQL => select * from cliente where 'status = 1'

If I simply put:

Cliente::all(); 
//SQL => select * from cliente

SQL will not have the filter, ie Local Scope needs to be invoked to work.

Even with Global Scope and Local Scope , nothing prevents the continuation of filters, ordering, joining of tables, etc. these two means are to facilitate non-repetition of code, standardizing and assisting in the development and maintenance of the code.

    
09.09.2016 / 03:41