pablomac's avatar

Error when using create or save related to polymorphic relationships

I can't seem to get polymorphic MorphMany relationships working correctly, both in an app that I'm working on and in a clean app I created in Google's Firebase Studio just to test the issue.

Here's a video model which is one of multiple models that will have a one-to-many polymorphic relationship with the image model:

And here's the image model:

Now, when I try to do $video = Video::create(['url' => 'http://example.com/my_test_video.mp4']);, I get the following error:

SQLSTATE[HY000]: General error: 1 table images has no column named imageable_id (Connection: sqlite, SQL: insert into "images" ("url", "imageable_id", "imageable_type", "updated_at", "created_at") values (images/post_image_1.jpg, 1, App\Models\Post, 2025-05-01 05:20:21, 2025-05-01 05:20:21))

I don't understand why it would expect to find an imageable_id column in the images table, instead of using the imageables table.

If anyone notices what I'm doing wrong, please let me know! Am I using create() in the correct way? The Laravel docs only seem to detail how to access data for models that have polymorphic relationships, not create it.

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The error message and your code suggest a misunderstanding of how Laravel's polymorphic relationships work.

Key Point:
For a MorphMany relationship, the foreign key columns (imageable_id and imageable_type) must exist on the related table—in this case, the images table, not a pivot table like imageables.

Why the Error Occurs

Laravel expects the images table to have imageable_id and imageable_type columns because that's how it links an image to its parent (e.g., a Video, Post, etc.) in a polymorphic relationship.

You do NOT need an imageables table.
The images table itself should have these columns.


Solution

1. Update Your Migration for images Table

Make sure your images table migration includes the polymorphic columns:

Schema::create('images', function (Blueprint $table) {
    $table->id();
    $table->string('url');
    $table->morphs('imageable'); // This adds imageable_id (unsignedBigInteger) and imageable_type (string)
    $table->timestamps();
});

If your table is already created, you can add the columns with a migration:

Schema::table('images', function (Blueprint $table) {
    $table->morphs('imageable');
});

Then run:

php artisan migrate

2. Creating Related Images

Now, you can create a video and attach images like this:

$video = Video::create(['url' => 'http://example.com/my_test_video.mp4']);

$video->images()->create([
    'url' => 'images/post_image_1.jpg',
]);

This will automatically set the imageable_id and imageable_type fields on the new image.


3. Summary

  • You do NOT need an imageables table.
  • The images table must have imageable_id and imageable_type columns.
  • Use $video->images()->create([...]) to create related images.

References:

If you follow these steps, your polymorphic relationship should work as expected!

1 like

Please or to participate in this conversation.