DEV Community

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

Posted on

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.

Top comments (0)