Skip to main content

Qu’est-ce qu’un scope

Les scopes Eloquent permettent de regrouper des contraintes réutilisables sur une requête. Il en existe deux types.

Scopes locaux

Définition

Les scopes locaux sont définis en appliquant l’attribut #[Scope] à une méthode du modèle.
L’attribut #[Scope] se trouve dans le namespace Illuminate\Database\Eloquent\Attributes. C’est une syntaxe native PHP 8.0+.

Utilisation

Les scopes définis s’invoquent comme des méthodes. Le chaînage est possible.

Passage de paramètres

À partir du second argument, la méthode de scope peut recevoir des paramètres supplémentaires.
Passez l’argument tel quel lors de l’appel.

Combinaison avec orWhere

Combiner des scopes avec orWhere peut nécessiter un groupe logique.

Scopes globaux

Mécanisme

Un scope global est une classe qui implémente l’interface Illuminate\Database\Eloquent\Scope. Cette interface ne demande qu’une seule méthode apply.
Ajoutez les contraintes au query builder dans la méthode apply.

Création d’une classe de scope global

Générez un squelette avec la commande make:scope.
app/Models/Scopes/ActiveScope.php est généré.

Application au modèle

1

Enregistrement via l'attribut #[ScopedBy] (recommandé)

Sous Laravel 13, l’attribut #[ScopedBy] est la manière la plus simple.
Vous pouvez spécifier plusieurs scopes dans un tableau.
2

Enregistrement manuel via la méthode booted()

Une autre méthode consiste à surcharger la méthode booted et à y appeler addGlobalScope.
Une fois le scope global ajouté, chaque requête (comme User::all()) reçoit automatiquement WHERE is_active = 1.

Scope global via closure anonyme

Pour un scope simple qui ne mérite pas un fichier séparé, définissez-le via une closure.
Pour exclure ultérieurement un scope défini via closure, il faut utiliser son nom (chaîne) plutôt qu’un nom de classe.

Exclure un scope global

Il y a des situations où vous voulez désactiver un scope pour certaines requêtes.

Interne du framework : SoftDeletingScope

Voir comment le trait standard SoftDeletes de Laravel utilise un scope global vous éclaire sur le pattern d’implémentation. SoftDeletingScope implémente l’interface Scope.
withTrashed() appelle en réalité withoutGlobalScope($this). Autrement dit, il exclut SoftDeletingScope lui-même pour permettre la récupération des enregistrements supprimés.
De même, onlyTrashed() exclut le scope puis ajoute whereNotNull('deleted_at').
Bien que la méthode extend ne soit pas définie dans l’interface Scope, le builder Eloquent l’appelle automatiquement si le scope la possède. C’est utile pour ajouter des macros personnalisées.

Cas d’usage pratiques

Multi-tenant : filtrage automatique par tenant ID

Dans une application SaaS, il est essentiel d’appliquer automatiquement un filtre de tenant à toutes les requêtes.
Ainsi, un simple Post::all() ne renvoie que les données du tenant de l’utilisateur authentifié.

Filtre publié/non publié

Cas où l’administration doit voir aussi les brouillons, mais le frontend uniquement les posts publiés.
En admin, excluez le scope avec withoutGlobalScope.

Utilisez addSelect plutôt que select

Pour ajouter une colonne dans un scope global, utilisez addSelect et non select. Utiliser select écrasera les colonnes que l’appelant a définies dans son select.

Étapes suivantes

Casts personnalisés Eloquent

Apprenez à implémenter votre logique de transformation d’attributs sous forme de cast personnalisé et à tirer parti du pattern Value Object.
Dernière modification le 13 juillet 2026