Larastan关联方法报错原因?如何修复ModelHasPermission的user关联问题
解决Larastan提示ModelHasPermission关联不存在及未定义属性错误
问题场景
在Laravel 11 + larastan/larastan 2.9项目里,运行这段代码时:
$managers = ModelHasPermission ::getByPermissionId(PERMISSION_APP_MANAGER) ->with('user') // 错误指向第37行 ->get(); foreach ($managers as $manager) { $manager->user->notify(new ContactUsSentNotification(contactUs: $contactUs, manager: $manager->user)); }
用level=6执行Larastan会报这些错:
37 Relation 'user' is not found in App\Models\ModelHasPermission model. 43 Access to an undefined property App\Models\ModelHasPermission::$user. 💡 Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property 43 Access to an undefined property App\Models\ModelHasPermission::$user. 💡 Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined
但app/Models/ModelHasPermission.php明明已经定义了user关联方法:
<?php namespace App\Models; use DB; use Illuminate\Database\Eloquent\Model; class ModelHasPermission extends Model { protected $table = 'model_has_permissions'; protected $primaryKey = 'id'; ... public function user() { return $this->belongsTo(User::class, 'model_id'); } }
解决步骤
1. 给关联方法加返回类型声明
Larastan需要明确的类型提示才能识别关联,直接给user()方法加上返回类型:
use Illuminate\Database\Eloquent\Relations\BelongsTo; // ... public function user(): BelongsTo { return $this->belongsTo(User::class, 'model_id'); }
2. 确保自定义查询方法返回正确类型
getByPermissionId是自定义静态方法的话,要保证它返回Illuminate\Database\Eloquent\Builder<ModelHasPermission>类型,不然Larastan认不出后续的链式调用:
use Illuminate\Database\Eloquent\Builder; // ... public static function getByPermissionId(int $permissionId): Builder { return self::where('permission_id', $permissionId); }
3. 可选:给关联属性加PHPDoc注释
要是想让提示更明确,还能在模型类上加PHPDoc注释,声明$user属性的类型:
/** * @property-read \App\Models\User|null $user */ class ModelHasPermission extends Model { // ... }
原理说明
Larastan在level=6的严格模式下,必须要有明确的类型信息才能推断关联关系和属性类型。给关联方法加返回类型、保证查询构建器的正确类型,就能让Larastan准确识别模型的关联方法和对应的属性了。
内容的提问来源于stack exchange,提问作者mstdmstd
相关产品推荐
相关产品推荐

