larastan / larastan

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using `sole()` on a BelongsTo relation returns Model instead of Model Extension

Roardom opened this issue · comments

  • Larastan Version: 2.9.4
  • Laravel Version: 10.48.7

Description

When accessing a BelongsTo relation, such as:

$topic = $post->topic()->sole();

$topic is seen as an Illuminate\Database\Eloquent\Model instead of an App\Models\Topic. ->firstOrFail() seems to work.

Laravel code where the issue was found

<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
 * App\Models\Post.
 *
 * @property int                             $id
 * @property string                          $content
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property int                             $user_id
 * @property int                             $topic_id
 */
class Post extends Model
{
    use HasFactory;

    /**
     * Belongs To A Topic.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<Topic, self>
     */
    public function topic(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(Topic::class);
    }
}

Thank you!

Adding sole method to our stubs solves your problem.

Thank you!

Adding sole method to our stubs solves your problem.

I tried adding a sole() method to some of the stubs, but couldn't get it to work. Would you mind pointing out which file I have to add it in, and I can send a PR?

🤯

Seems like we already have that!

/**
* Execute the query and get the first result if it's the sole matching record.
*
* @param array<int, (model-property<TModelClass>|'*')>|model-property<TModelClass>|'*' $columns
* @phpstan-return TModelClass
*/
public function sole($columns = ['*']);

What type is topic?

\PHPStan\dumpType($post->topic());

What type is topic?

\PHPStan\dumpType($post->topic());
phpstan: Dumped type: Illuminate\Database\Eloquent\Relations\BelongsTo<App\Models\Topic, App\Models\Post>