Skip to content

[12.x] Add template variables to scope #55830

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

wietsewarendorff
Copy link
Contributor

I run phpstan with max level on the example from the docs:

<?php

namespace App\Models\Scopes;

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

class AncientScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     */
    public function apply(Builder $builder, Model $model): void
    {
        $builder->where('created_at', '<', now()->subYears(2000));
    }
}

I get the error-message:

Method App\Models\Scopes\AncientScope::apply() has parameter $builder with generic class
Illuminate\Database\Eloquent\Builder but does not specify its types: TModel
🪪 missingType.generics

Therefore I specify the type like this:

<?php

namespace App\Models\Scopes;

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

class AncientScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @template TModel of Model
     *
     * @param Builder<TModel> $builder
     * @param TModel $model
     */
    public function apply(Builder $builder, Model $model): void
    {
        $builder->where('created_at', '<', now()->subYears(2000));
    }
}

But now I get a different message:

Parameter #1 $builder (Illuminate\Database\Eloquent\Builder<TModel of Illuminate\Database\Eloquent\Model>)
of method App\Models\Scopes\AncientScope::apply() should be contravariant with parameter $builder
(Illuminate\Database\Eloquent\Builder) of method Illuminate\Database\Eloquent\Scope::apply()
🪪 method.childParameterType
✏️ app/Models/Scopes/AncientScope.php

By setting the templates variable on the scope-interface I can even drop the docblocks on the Ancient-scope and phpstan is all green.

@wietsewarendorff wietsewarendorff changed the title add template variables to scope [12.x] Add template variables to scope May 22, 2025
@Muffinman
Copy link
Contributor

Muffinman commented May 22, 2025

TModel is specific to your IDE helper? barryvdh/laravel-ide-helper#1609

Not sure it's something that belongs in the Laravel repo.

Sorry I'm probably wrong, I can see other instances of this in the code base.

@wietsewarendorff
Copy link
Contributor Author

wietsewarendorff commented May 22, 2025

TModel is specific to your IDE helper? barryvdh/laravel-ide-helper#1609

It's from the template specified, just like in the SoftDeletingScope

Edit: no problem, thanks for looking into it!

@taylorotwell taylorotwell merged commit f9ffdc1 into laravel:12.x May 23, 2025
61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants