Skip to main content

Cosa sono gli scope

Gli scope di Eloquent sono un meccanismo che permette di raggruppare e riutilizzare vincoli sulle query. Esistono due tipi di scope.

Local scope

Definizione

I local scope si definiscono applicando l’attributo #[Scope] a un metodo del modello.
L’attributo #[Scope] si trova nel namespace Illuminate\Database\Eloquent\Attributes. È sintassi nativa PHP dalla versione 8.0.

Utilizzo

Gli scope definiti si invocano come metodi. Puoi anche concatenarli.

Passaggio di parametri

Nei metodi scope puoi definire parametri aggiuntivi dopo il secondo argomento.
Alla chiamata, gli argomenti si passano direttamente.

Combinazione con orWhere

Concatenando uno scope con orWhere, può essere necessario un raggruppamento logico.

Global scope

Meccanismo

Un global scope è una classe che implementa l’interfaccia Illuminate\Database\Eloquent\Scope. L’interfaccia richiede un unico metodo apply.
All’interno del metodo apply aggiungi il vincolo al query builder.

Creare una classe di global scope

Genera lo scaffold con il comando make:scope.
Viene generato app/Models/Scopes/ActiveScope.php.

Applicazione al modello

1

Registrare con l'attributo #[ScopedBy] (consigliato)

In Laravel 13 il modo più semplice è usare l’attributo #[ScopedBy].
Puoi indicare più scope in un array.
2

Registrazione manuale nel metodo booted()

Puoi anche fare override di booted e chiamare addGlobalScope.
Aggiungendo il global scope, tutte le query come User::all() ricevono automaticamente WHERE is_active = 1.

Global scope con closure anonime

Per scope semplici, per cui non vale la pena creare una classe a parte, si può usare una closure.
Per escludere in seguito uno scope definito come closure devi usare il nome dello scope (stringa), non il nome della classe.

Esclusione di un global scope

A volte vuoi disattivare uno scope per una query specifica.

Interno del framework: SoftDeletingScope

Osservare come il trait standard SoftDeletes usa i global scope fa capire i pattern implementativi. SoftDeletingScope implementa l’interfaccia Scope.
In pratica withTrashed() chiama withoutGlobalScope($this). Escludendo lo stesso SoftDeletingScope, i record cancellati diventano di nuovo recuperabili.
Anche onlyTrashed() esclude lo scope e aggiunge whereNotNull('deleted_at').
L’interfaccia Scope non definisce il metodo extend, ma il builder di Eloquent, se lo scope lo espone, lo chiama automaticamente. Puoi sfruttarlo per aggiungere macro personalizzate.

Casi d’uso pratici

Multi-tenant: filtro automatico per tenant ID

Nelle applicazioni SaaS è essenziale che tutte le query filtrino automaticamente per l’ID del tenant.
Ora basta Post::all() per ottenere solo i dati del tenant dell’utente autenticato.

Filtro pubblicato/non pubblicato

Quando nel back office vuoi vedere anche i post non pubblicati, ma sul frontend solo quelli pubblicati.
Nel back office escludi lo scope con withoutGlobalScope.

Usa addSelect invece di select

Quando aggiungi colonne all’interno di un global scope, usa addSelect invece di select. Con select sovrascriveresti le colonne che il chiamante ha già indicato.

Prossimi passi

Cast personalizzati di Eloquent

Impara a implementare la logica di conversione degli attributi come cast personalizzato e a utilizzare il pattern Value Object.
Ultima modifica il 13 luglio 2026