plugin icon indicating copy to clipboard operation
plugin copied to clipboard

[Feature Request]: Support Union Type For Relationship Method Return Types

Open FeBe95 opened this issue 6 months ago • 1 comments

Feature Description

Sometimes, Eloquent model relationships can be "dynamic", returning one of multiple specific models. Here are some examples, how the relationship definitions could look like:

class FooBar extends Model
{
    public function resource(): MorphTo
    {
        return $this->morphTo(null, 'resource_type', 'resource_id', 'resource_id');
    }
    
    public function parentEntity(): HasOne
    {
        $relatedModel = self::entities[$this->entityId];

        return $this->hasOne($relatedModel, 'entity_id', 'parent_entity_id');
    }
}

Currently, this will create the following helper code:

namespace App\Models {
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\MorphTo;

    /**
     * @property Model $resource
     * @method MorphTo resource()
     */
    class PerformanceData extends Model {}
}

Note, how parentEntity() is not present:

/*
 * @property Model $parentEntity
 * @method HasOne parentEntity()
 */

In our code, we usually go one step further and define all possible models in a PHPDoc @return tag:

class FooBar extends Model
{
    /**
     * @return MorphTo<AdGroup|AdItem|Campaign|Keyword, $this>
     */
    public function resource(): MorphTo
    {
        return $this->morphTo(null, 'resource_type', 'resource_id', 'resource_id');
    }
    
    /**
     * @return HasOne<Video|Image|Gif, $this>
     */
    public function parentEntity(): HasOne
    {
        $relatedModel = self::entities[$this->entityId];

        return $this->hasOne($relatedModel, 'entity_id', 'parent_entity_id');
    }
}

I don't know how Laravel Idea parses the PHP code, but it would be great if it would also the PHPDoc return type(s).

[!NOTE] Possible formats:

/**
 * HasOne<Video|Image|Gif, $this>
 */
/**
HasOne<Video, $this>|HasOne<Image, $this>|HasOne<Gif, $this>
 */

Summary

This feature request consists of one base and one additional request:

  1. Instead of not adding a relationship at all, fall back to return type Model when specific model type cannot be determined
  2. Additionally, the PHPDoc block could be parsed, and specific generic templates types could be extracted from there

FeBe95 avatar Jun 23 '25 17:06 FeBe95

Thanks for your feedback! We started adding generic type hints to different places already, Builder methods already hinted, so I think we can do this to polymorphic relations too. I'll add this into internal task tracker.

gorbunov avatar Jun 24 '25 05:06 gorbunov