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