DEV Community

Cover image for Easy Polymorphic Relationships in Laravel ! One To One Relationship ?
Kepson Diaz
Kepson Diaz

Posted on

2

Easy Polymorphic Relationships in Laravel ! One To One Relationship ?

*Introduction : *

Polymorphism in Laravel is a powerful feature that allows a model to belong to multiple other models. It enables a single association to be linked to various models, providing flexibility and reusability in database relationships.

*One to One Relationship : *

In a one-to-one polymorphic relationship, a model can belong to one and only one other model, but that model can have multiple types it can belong to.

For example, a Product and a Post may share a polymorphic relation to an Image model. Using a one-to-one polymorphic relation allows you to have a single table of unique images that may be associated with products and post.

To establish a one-to-one polymorphic relationship in Laravel, you can use the morphOne and morphTo methods.
For our example, the morphOne method is used in the child model: Image to define the relationship, while the morphTo method is used in the parent models: Product and Post to define the inverse relationship.

First, let's examine the table structure:

products
    id - integer
    name - string

posts
    id - integer
    name - string

images
    id - integer
    url - string
    imageable_id - integer
    imageable_type - string
Enter fullscreen mode Exit fullscreen mode

Notice :
imageable_id column will contain the ID value of the products or posts, while the imageable_type column will contain the class name of the parent model.

The models structure will look like this:

<?php

namespace App\Models;

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

class Image extends Model
{
    /**
     * Get the parent imageable model (product or post).
     */
    public function imageable(): MorphTo
    {
        return $this->morphTo();
    }
}
Enter fullscreen mode Exit fullscreen mode
<?php

namespace App\Models;

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

class Product extends Model
{
    /**
     * Get the product's image.
     */
    public function image(): MorphOne
    {
        return $this->morphOne(Image::class, 'imageable');
    }
}
Enter fullscreen mode Exit fullscreen mode
<?php

namespace App\Models;

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

class Post extends Model
{
    /**
     * Get the post's image.
     */
    public function image(): MorphOne
    {
        return $this->morphOne(Image::class, 'imageable');
    }
}
Enter fullscreen mode Exit fullscreen mode

Once your database table and models are defined, you may access the relationships via your models.
Example :

use App\Models\Image;

$image = Image::find(1);

$imageable = $image->imageable;
Enter fullscreen mode Exit fullscreen mode

The imageable relation on the Image model will return either a Product or Post instance.

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more