Polymorphic One-One

What is Polymorphic One-To-One?

A Polymorphic One-to-One relationship allows a model to be associated with exactly one related model, but that related model can belong to multiple different parent models.

👉 Example:

  • A Company has one Logo.
  • A School also has one Logo.
  • Both share the same logos table via polymorphic one-to-one.

So the relation is:

Company → Logo
School → Logo

Flow diagram


Migration:

Use this command to generate a migration for creating a tables:

php artisan make:migration create_polymorphic_one_to_one_tables


Migration File

public function up(): void
{
    // Companies table
    Schema::create('companies', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });

    // Schools table
    Schema::create('schools', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });

    // Logos table (polymorphic)
    Schema::create('logos', function (Blueprint $table) {
        $table->id();
        $table->string('image');
        $table->morphs('logoable'); // logoable_id & logoable_type
        $table->timestamps();
    });
}

public function down(): void
{
    Schema::dropIfExists('logos');
    Schema::dropIfExists('schools');
    Schema::dropIfExists('companies');
}


Run Migration

php artisan migrate

Tables

companies table
id name created_at updated_at
schools table
id name created_at updated_at
logos table
id name logoable_id logoable_type created_at updated_at

Model:

Generate a model with Artisan:

php artisan make:model Company
php artisan make:model School
php artisan make:model Logo

This generates 3 files Company.php , School.php and Logo.php


Company.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Company extends Model
{
    protected $fillable = ['name'];

    public function logo()
    {
        return $this->morphOne(Logo::class, 'logoable');
    }
}


School.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class School extends Model
{
    protected $fillable = ['name'];

    public function logo()
    {
        return $this->morphOne(Logo::class, 'logoable');
    }
}


Logo.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Logo extends Model
{
    protected $fillable = ['image'];

    public function logoable()
    {
        return $this->morphTo();
    }
}

CRUD Examples

Create

use App\Models\Company;
use App\Models\School;

// Create a Company with Logo
$company = Company::create(['name' => 'Tech Corp']);
$company->logo()->create(['image' => 'tech_logo.png']);

// Create a School with Logo
$school = School::create(['name' => 'Green Valley School']);
$school->logo()->create(['image' => 'school_logo.png']);
Output
companies table
id name created_at updated_at
1 Tech Corp 2025-08-25 14:55:55 2025-08-25 14:55:55
schools table
id name created_at updated_at
1 Green Valley School 2025-08-25 14:55:55 2025-08-25 14:55:55
logos table
id name logoable_id logoable_type created_at updated_at
1 tech_logo.png 1 App\Models\Company 2025-08-25 14:55:55 2025-08-25 14:55:55
2 school_logo.png 1 App\Models\School 2025-08-25 14:55:55 2025-08-25 14:55:55

Read

// Get Company Logo
$company = Company::find(1);
echo $company->logo->image; // tech_logo.png

// Get School Logo
$school = School::find(1);
echo $school->logo->image; // school_logo.png

// Get Logo Owner (Company or School)
$logo = Logo::find(1);
echo $logo->logoable->name; // Tech Corp

Update

// Update Company Logo
$company = Company::find(1);
$company->logo->update(['image' => 'tech_logo_updated.png']);

// Update School Logo
$school = School::find(1);
$school->logo->update(['image' => 'school_logo_updated.png']);

Delete

// Delete a Logo
$company = Company::find(1);
$company->logo->delete();

// Delete a School (Logo will remain unless handled manually)
$school = School::find(1);
$school->delete();

Eager Loading

// Get Companies with Logos
$companies = Company::with('logo')->get();

// Get Schools with Logos
$schools = School::with('logo')->get();

// Get Logos with parent model (Company/School)
$logos = Logo::with('logoable')->get();

Whereisstuff is simple learing platform for beginer to advance level to improve there skills in technologies.we will provide all material free of cost.you can write a code in runkit workspace and we provide some extrac features also, you agree to have read and accepted our terms of use, cookie and privacy policy.
© Copyright 2024 www.whereisstuff.com. All rights reserved. Developed by whereisstuff Tech.