Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

chrisgrim's avatar

Setting up Polymorphic relationship correctly

Im trying to setup a polymorphic relationship but struggling. Here are my databases

public function up()
    {
        Schema::create('features', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->integer('order')->unsigned()->default(0);
            $table->foreignId('featurer_id');
            $table->string('featurer_type', 50);
            $table->timestamps();
        });

        Schema::create('feature_section', function(Blueprint $table) {
            $table->foreignId('feature_id');
            $table->foreignId('section_id');
            $table->timestamps();
        });
    }
Schema::create('sections', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->string('name', 50);
            $table->timestamps();
        });

Then in my models I have Section.php

class Section extends Model
{
    use HasFactory;

    /**
     * Get the featured for the section .
     */
    public function featured()
    {
        return $this->belongsToMany(Feature::class);
    }
}

and Feature.php

class Feature extends Model
{
    use HasFactory;

    /**
    * The relations to eager load on every query. I am adding shows here because I need to filter by dates for the search
    *
    * @var array
    */
    protected $with = ['featureable'];

    /**
     * Get the section that has this featured
     */
    public function features()
    {
        return $this->belongsToMany(Section::class);
    }

    /**
     * Get the section that has this featured
     */
    public function featureable()
    {
        return $this->morphTo();
    }
}

However when I do

return Section::all()->load('featured');

I get

{
"id": 1,
"user_id": 1,
"name": "homepage",
"created_at": null,
"updated_at": null,
"featured": [
{
"id": 1,
"user_id": 1,
"name": "a",
"order": 0,
"featurer_id": 1,
"featurer_type": "App\Models\Curated\Community",
"created_at": null,
"updated_at": null,
"pivot": {
"section_id": 1,
"feature_id": 1
},
"featureable": null
},
{
"id": 2,
"user_id": 1,
"name": "x",
"order": 0,
"featurer_id": 67,
"featurer_type": "App\Models\Event",
"created_at": null,
"updated_at": null,
"pivot": {
"section_id": 1,
"feature_id": 2
},
"featureable": null
}
]
}
]

and it doesn't include the community or event model with the featured model, just leaves it null. Thanks!

0 likes
8 replies
talel's avatar
talel
Best Answer
Level 16

I believe that Laravel does it best to understand what are the featureable fields on the feature table, but the naming convention is a bit off.

You can try two different solutions.

First: On your migration instead of specifying the polyMorphic fields id,type try to use the helper method

            $table->morphs('featureable');

The second option, if you want to stick to the names you got for the tables:

			$table->foreignId('featurer_id');
            $table->string('featurer_type', 50);

You should explicitly pass as arguments what are the column to identify that relationship.

    return $this->morphTo(__FUNCTION__, 'featurer_type', 'featurer_id');

You can visit the documentation for more detailed explanation: Key Conventions

Good luck!

1 like
talel's avatar

Yep, that as well 💪🏻

1 like
webrobert's avatar

ha, and what @talelmishali said. Also, I think the general idea with morph naming is to use real words, like commentable, still a real word. Featurable doesn't sus out. But I'd use it ;)

chrisgrim's avatar

I am having the hardest time naming this! Is there a standard name for this?

chrisgrim's avatar

It worked just by changing

            $table->morphs('featureable');
1 like

Please or to participate in this conversation.