What’s the point of a Cope on the Laravel?

Asked

Viewed 2,023 times

3

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

As I do not know much English, I was left with some doubts about the use.

  • What is the purpose of these methods where we define the prefix scope in the models?

  • What is the difference between Local and Global?

Example of documentation (site 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);
    }
}

Example documentation (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);
        });
    }
}

1 answer

5

  • What is the purpose of these methods where we define the prefix Scope in models?

It is intended to facilitate consultation routines in your model (Eloquent), with previous query functionality SQL, thus helping in the development and standardization of consultations. It is divided into Global Scope or Local Scope.


  • What is the difference between Local and Global?

Global Scope limits or restricts its model to run previous filters (where, order by) in all consultations SQL of 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 exclusion of a given record where the determinant is a date with the value null the query brings the record, different from 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 code Cliente::all(), will bring the list of all customers who were not deleted, because, the Global Scope of traits SoftDeletes has a restrictive and comprehensive filter for all queries (select * from clientes where deleted_at is null). If by chance you want to bring all the records including the deleted ones do the command Cliente::withTrashed()->get(), being an elegant way to circumvent this Global Scope. A radical way to eliminate all Global Scope would be so Cliente::withoutGlobalScopes()->get().

Already in the Local Scope is a prepared filter, or shortcut, that is executed only by calling the method, being different from the Global Scope which 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'];

}

Exists in that model Client a scopeStatus that I set a filter where status = 1, but, I need to invoke it so that it will be executed and the query receive more this filter.

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

if I just 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, sortings, junction of tables, etc. these two means are to facilitate the nonrepetition of code, standardizing and assisting in the development and maintenance of the code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.