Les scopes Eloquent Laravel (Local et Global)

Scope Local


Avec Laravel et son ORM Eloquent, on peut facile créer des requêtes pour récupérer des données de la base. Par exemple, si on veut récupérer tous les utilisateurs de la table users, on peut faire :


$users = User::get();


Mais parfois, on désire récupérer tous les utilisateurs qui sont actifs, c'est à dire qui ont un champs 'active' à 1.

On pourrait faire :


$users = User::where('active', 1)->get();


Et c'est là que peut intervenir le Scope local.


Dans votre modèle User, voici ce que nous allons faire :


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


Ainsi, dans nos contrôleur, partout où nous aurons besoin de récupérer les utilisateurs actifs, nous pourrons appeler la méthode comme ceci :


$users = User::active()->get();


Scope Global


Nous allons voir maintenant une fonctionnalité qui peut vous êtes très utile. La notion de scope global.

Prenons par exemple un modèle User. Maintenant sur notre site, on veut par défaut récupérer tous les utilisateurs qui ont validés leur compte.


Nous allons commencer par créer un dossier Scopes dans app. Puis dedans, nous allons créer un fichier ValidateScope.php

Voici les quelques lignes à insérer : (on imagine qu'on a un champ validated_at dans notre table users)


<?php

namespace App\Scopes;

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

class ValidateScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->whereNotNull('validated_at');
    }
}

Dans le modèle User.php, il nous suffira d'appeler le scope précédemment créé.


<?php

namespace App\Models;

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

class User extends Model
{
    protected static function booted()
    {
        static::addGlobalScope(new ValidateScope);
    }
}

Maintenant, chaque requête qui utilise le modèle User aura en plus la condition validated_at non null.


Dernier point important, si à un moment on désire avoir tous les utilisateurs, même ceux qui n'ont pas validés leur compte, il faudra invalider sur notre requête le scope global.


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


Cours rédigé par Vincent, publié le 23/03/2021