7 Notes, 0 Own notes, 0 Own private notes, 0 Own public notes

Laravel Model Local Scoping with attributes

The new "way" of using local scopes in laravel is with using attributes.

The old way:

old way ...
1// feeds on magic...
2public function scopeLike(Builder $query, string $pattern): Builder
3{
4    return $query->where('name','like',"%$pattern%");
5}
6
7// Usage:
8User::like('foo')->get();

The new way:

new way ...
 1use Illuminate\Database\Eloquent\Attributes\Scope;
 2
 3#[Scope]
 4public function like2(Builder $query, string $pattern): Builder
 5{
 6    return $query->where('name','like',"%$pattern%");
 7}
 8
 9// Usage:
10User::query()->like('foo')->get();

The new version does not work with the old query method:

Error: Non-static method App\Models\User::like() cannot be called statically.

Well, of course the scope could be declared as static method, but...

  • then $this is not accessible,

  • auto injecting the Builder does not work,

    TypeError:  App\Models\User::like(): Argument #1 ($query) must be of type Illuminate\Database\Eloquent\Builder, string given, called on line 1.

    chaining does not work,

  • it is bad practice to use mismatched functions for the same functionality...

The good way:

Always use the query() method, it work in both scenarios:

the way ...
1// Usage:
2User::query()->like('foo')->get();

The old way: Laravel 11 Local Scopes

The new way: Laravel 12 Local Scopes

2025-10-14 17:03:34
Powered by: Scriptum Version: v0.7.0-dev