In this laravel 9 polymorphic relationship example, I will discuss about polymorphic relationship in laravel. In this example, I will discuss about laravel polymorphic one to one example. I will discuss about what is polymorphic relationship is and when we need this relationship in the Laravel application.

In this example, we will see polymorphic relationship laravel, laravel polymorphic one to one example, laravel polymorphic migration and laravel save polymorphic relationship. You need to just follow this tutorial to learn the above scenarios.

laravel-9-one-to-one-polymorphic-relationship-example

Polymorphic Relationships in Laravel

In Laravel, a polymorphic relationship allows the child model to belong to more than one type of model using a single association. For example, imagine you are building an application that allows users to share their feedback for posts and videos. In such an application, a Comment model might belong to both the Blog and Video models. Now we know what is polymorphic relationship in laravel. Now we will see when we will use it in our Laravel application.

One To One (Polymorphic) Scenario

Taking the example mentioned above into consideration, we have two entities: Post and User. To allow for images on each of these, we can decide to set up our database like this:

posts
    id - integer
    name - string
 
users
    id - integer
    name - string
 
images
    id - integer
    url - string
    imageable_id - integer
    imageable_type - string

 

If we avoid polymorphic relationship schema, then our database schema will look like:

posts:
  id
  title
  content
  
posts_images:
  id
  post_id
  image
  date
  
users:
  id
  name
  
users_images:
  id
  user_id
  image
  date

 

But look at that our polymorphic schema, how cool it is.  Here, we have three entities: PostUser, and ImagePost can have ImageUser can have Image. Let's create our migration like:

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
    $table->text('content');
});

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->text('name');
});

Schema::create('images', function (Blueprint $table) {
    $table->increments('id');
    $table->morphs(‘commentable’);
    $table->text('image');
    $table->date('date');
});

 

Read also: Laravel One To One/HasOne Eloquent Relationship Tutorial

 

Remember: $table→morphs('commentable') would automatically create two columns for the id and type using the text passed to it, so it will result in commentable_id and commentable_type.

 

Define One to One Polymorphic Relationship

Now let's define the one to one polymorphic relationship in our model class. 

app/Models/User.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
    /**
     * Get the user's image.
     */
    public function image()
    {
        return $this->morphOne(Image::class, 'imageable');
    }
}

 

Now define the relationship in the Post model like:

app/Models/Post.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Post extends Model
{
    /**
     * Get the post's image.
     */
    public function image()
    {
        return $this->morphOne(Image::class, 'imageable');
    }
}

 

Now define the relationship in the Image model like:

app/Models/Image.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Image extends Model
{
    /**
     * Get the parent imageable model (user or post).
     */
    public function imageable()
    {
        return $this->morphTo();
    }
}

 

To access the image for a User, we can use the image property declared in the model.

App\Http\Controllers\TestController.php

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index($id)
    {   
        $user = User::find($id);

        $user->image;
    }
}

 

For retrieving image on a post:

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index($id)
    {   
        $post = Post::find($id);

        $post->image;
    }
}

 

Save Polymorphic Relationship Data

If we want to save or create polymorphic relationship data then we can follow the below structure:

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index($id)
    {   
        $post = Post::find($id);

        $image = new Image;
        $image->image = "your_image";
 
        $post->image()->save($image);
    }
}

 

Read also: Laravel 9 Many To Many | BelongsToMany Eloquent Relationship Tutorial

 

Conclusion

We have tried to discuss the basic application of polymorphic relationships and their possible use cases in laravel. We should also note that polymorphic relationships are not a perfect solution to everything and should only be used when convenient or feels like the right way to go.