Skip to main content
Category:

A one-to-one polymorphic relation is similar to a simple one-to-one relation; however, the target model can belong to more than one type of model on a single association. For example, a blog Post and a User may share a polymorphic relation to an Image model.

Using a one-to-one polymorphic relation allows you to have a single list of unique images that are used for both blog posts and user accounts. First, let's examine the table structure:

posts
    id - integer
    name - string

users
    id - integer
    name - string

images
    id - integer
    url - string
    imageable_id - integer
    imageable_type - string

Take note of the imageable_id and imageable_type columns on the images table. The imageable_id column will contain the ID value of the post or user, while the imageable_type column will contain the class name of the parent model. The imageable_type column is used by Eloquent to determine which "type" of parent model to return when accessing the imageable relation.

 

Next, let's examine the model definitions needed to build this relationship:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
    /**
     * Get the owning imageable model.
     */
    public function imageable()
    {
        return $this->morphTo();
    }
}

class Post extends Model
{
    /**
     * Get the post's image.
     */
    public function image()
    {
        return $this->morphOne('App\Models\Image', 'imageable');
    }
}

class User extends Model
{
    /**
     * Get the user's image.
     */
    public function image()
    {
        return $this->morphOne('App\Models\Image', 'imageable');
    }
}

 

Retrieving The Relationship

Once your database table and models are defined, you may access the relationships via your models. For example, to retrieve the image for a post, we can use the image dynamic property:

$post = App\Models\Post::find(1);

$image = $post->image;

 

You may also retrieve the parent from the polymorphic model by accessing the name of the method that performs the call to morphTo.

In our case, that is the imageable method on the Image model. So, we will access that method as a dynamic property:

$image = App\Models\Image::find(1);

$imageable = $image->imageable;

The imageable relation on the Image model will return either a Post or User instance, depending on which type of model owns the image.

If you need to specify custom type and id columns for the morphTo relation, always ensure you pass the relationship name (which should exactly match the method name) as the first parameter:

/**
 * Get the model that the image belongs to.
 */
public function imageable()
{
    return $this->morphTo(__FUNCTION__, 'imageable_type', 'imageable_id');
}

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook