larastan: False positive undefined methods on relations

  • Larastan Version: 0.7.2
  • --level used: 8

Description

It looks like version 0.7.2 introduced some false-positive errors :

Call to an undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::orderBy().
Call to an undefined method Illuminate\Database\Eloquent\Relations\MorphMany::where().    
Call to an undefined method Illuminate\Database\Eloquent\Relations\MorphMany::whereIn().
...

Laravel code where the issue was found

Some examples :

$user->load(['garages' => fn (BelongsToMany $builder) => $builder->orderBy('name')]);

$comments = $folder->comments()
            ->orderByDesc('created_at')
            ->with('media', fn (MorphMany $builder) => $builder->where('collection_name', CommentMedia::file()))
            ->get();

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 17 (1 by maintainers)

Most upvoted comments

@osteel There must be something else wrong going on. Can you add \PHPStan\dumpType($company->projects()) somewhere in code and share the result? Result should be something like Illuminate\Database\Eloquent\Relations\BelongsToMany<App\Project>

Thanks @canvural, it works perfectly !

Hi,

This should now be fixed as a side effect of #816 Although the error would still happen if you try to get the model from the relation. The issue referenced at https://github.com/nunomaduro/larastan/issues/804#issuecomment-815791796 needs to be solved in PHPStan, to completly solve this I guess.

@canvural that worked 👍

Does that mean Larastan also reads the body of the method? If that’s the case, I guess I should haven mentioned that Company is an abstract class, and that this is the actual method definition:

/**
 * The company's projects.
 *
 * @return BelongsToMany
 */
abstract public function projects(): BelongsToMany;

I’ve now changed it for BelongsToMany<Project> and that seems to have done the trick.

Is the relation defined in trait or something? Anyway in that case you can go back to using docblocks but you need to use @return BelongsToMany<Project>

@osteel BelongsToMany is generic in Larastan. And also Larastan can infer these generic parameters on its own. So if you remove

/**
 * @return BelongsToMany
 */

I beleve your issue will be solved. Having the retrn type in the method signature is enough.