Updated June 2026. Tested on Laravel 13 and PHP 8.4.

Imagine you need documents on several different things in your system: employees, customers, companies. The obvious approach is a separate documents table for each one, but they would all have the same shape, so you would be repeating yourself. A polymorphic relationship removes that repetition. One documents table serves every model, and each document knows which model and which record it belongs to.

We will add document support to an Employee and a Customer using a single Document model.

The documents table

Create the model and migration.

php artisan make:model Document -m

The two columns that make this work are documentable_id and documentable_type. Laravel gives you a helper that adds both at once.

public function up(): void
{
    Schema::create('documents', function (Blueprint $table) {
        $table->id();
        $table->string('file_name');
        $table->string('file_path')->nullable();
        $table->string('description')->nullable();
        $table->morphs('documentable');
        $table->timestamps();
    });
}

$table->morphs('documentable') adds documentable_id (the related record's id) and documentable_type (the related model's class name). So a document attached to employee 22 stores documentable_id = 22 and documentable_type = App\Models\Employee. That pair is how Laravel knows exactly what each document belongs to. Run the migration.

php artisan migrate

Define the relationship

On the Document model, add a morphTo method. Read morphTo as "belongs to, but the owner can be any model".

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class Document extends Model
{
    protected $fillable = ['file_name', 'file_path', 'description'];

    public function documentable(): MorphTo
    {
        return $this->morphTo();
    }
}

Then on each model that can own documents, add a morphMany pointing back at the documentable name.

use Illuminate\Database\Eloquent\Relations\MorphMany;

class Employee extends Model
{
    public function documents(): MorphMany
    {
        return $this->morphMany(Document::class, 'documentable');
    }
}

class Customer extends Model
{
    public function documents(): MorphMany
    {
        return $this->morphMany(Document::class, 'documentable');
    }
}

The two models share the exact same code, which is the whole point.

Save documents

Attach a document the same way for any owner. Saving through the relationship fills in both the id and the type.

$employee = Employee::find(22);

$employee->documents()->create([
    'file_name'   => 'passport-front.png',
    'description' => 'Passport front page',
]);
$customer = Customer::find(39);

$customer->documents()->create([
    'file_name'   => 'invoice-may-2026.pdf',
    'description' => 'Invoice for May 2026',
]);

Look in the table and you will see the type column doing its job.

id | file_name           | documentable_id | documentable_type
 1 | passport-front.png  | 22              | App\Models\Employee
 2 | invoice-may-2026.pdf| 39              | App\Models\Customer

Read documents

The documents come back as a collection, so reading them is the same on either model.

foreach ($employee->documents as $document) {
    echo $document->file_name;
}

And from a document you can go back to its owner, whatever type it is.

$document = Document::find(1);
$owner = $document->documentable; // an Employee or a Customer

Polymorphic relationships save a lot of repeated work whenever several models need to share a feature like documents, notes or comments. One table, one model, and any number of owners. If you have a question about polymorphic relationships in Laravel, leave it in the comments.