Skip to content

PHPStan Annotations

Laravel uses generics syntax for these types of relationships:

  • BelongsTo: BelongsTo<TRelatedModel, TDeclaringModel>
  • BelongsToMany: BelongsToMany<TRelatedModel, TDeclaringModel, TPivotModel= \Illuminate\Database\Eloquent\Relations\Pivot, TAccessor = 'pivot'>
  • HasOne: HasOne<TRelatedModel, TDeclaringModel>
  • HasMany: HasMany<TRelatedModel, TDeclaringModel>
  • HasManyThrough: HasManyThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>
  • HasOneThrough: HasOneThrough<TRelatedModel, TIntermediateModel, TDeclaringModel>
  • MorphOne: MorphOne<TRelatedModel, TDeclaringModel>
  • MorphMany: MorphMany<TRelatedModel, TDeclaringModel>
  • MorphTo: MorphTo<TRelatedModel, TDeclaringModel>
  • MorphToMany: MorphToMany<TRelatedModel, TDeclaringModel, TPivotModel = \Illuminate\Database\Eloquent\Relations\MorphPivot, TAccessor = 'pivot'>

Examples:

php
final class Member extends Model
{
    /** @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Modules\Team\Models\Team, $this> */
    public function team(): BelongsTo
    {
        return $this->belongsTo(Team::class);
    }

    /** @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<\App\Modules\LocalGroup\Models\LocalGroup, $this> */
    public function localGroups(): BelongsToMany
    {
        return $this->belongsToMany(LocalGroup::class, 'local_group__local_group_members')
            ->withPivot('role');
    }

    /** @return \Illuminate\Database\Eloquent\Relations\HasOne<Address, $this> */
    public function address(): HasOne
    {
        return $this->hasOne(Address::class);
    }

    /** @return \Illuminate\Database\Eloquent\Relations\HasMany<Post, $this> */
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }

    /** @return \Illuminate\Database\Eloquent\Relations\HasManyThrough<\App\Modules\Course\Models\QuizAnswer, \App\Modules\Course\Models\CourseEnrollment, $this> */
    public function quizAnswers(): HasManyThrough
    {
        return $this->hasManyThrough(QuizAnswer::class, CourseEnrollment::class);
    }

    /** @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Masterclass, $this> */
    public function masterclasses(): MorphToMany
    {
        return $this->morphToMany(Masterclass::class, 'attendee', 'masterclass__registrations');
    }

    /** @return \Illuminate\Database\Eloquent\Relations\MorphToMany<Registration, $this> */
    public function masterclassRegistrations(): MorphMany
    {
        return $this->morphMany(Registration::class, 'attendee');
    }
}

final class Registration extends Model
{
    /** @return \Illuminate\Database\Eloquent\Relations\MorphTo<Attendee&Model, $this> */
    public function attendee(): MorphTo
    {
        return $this->morphTo('attendee')->withTrashed();
    }
}