How To Define One To One Polymorphic Relationships In Laravel

admin_img Posted By Bajarangi soft , Posted On 08-09-2020

A polymorphic relationship allows the target model to belong to more than one type of model using a single association.

How To Define One To One Polymorphic Relationships In Laravel

One To One Polymorphic Relationships

Lets start.
How to define One To One Polymorphic Eloquent Relationship

1.Create laravel project and connect to database in .env file.

composer create-project laravel/laravel MusicApp  --prefer-dist
 


2.Create Model and Migrate it.
To implement  One To One Polymorphic Relationships in Laravel, we need models: Posts,Image and  User .

Now we need to create Post,Image  and  User models in fresh project so for that run below commands in comand prompt.
 
php artisan make:model Post -m

php artisan make:model User -m

php artisan make:model Image -m


3.After Created Models we need to Implement code in Model and migration files as below

Migration files
2020_09_07_111619_create_posts_table.php

 

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

   
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}


2020_09_07_000000_create_users_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}


2020_09_07_123233_create_images_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateImagesTable extends Migration
{
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('url');
            $table->integer('imageable_id');
            $table->string('imageable_type');
            $table->timestamps();
        });
    }
    
    public function down()
    {
        Schema::dropIfExists('images');
    }
}

Migrate the schema files using the following command

php artisan migrate


Models
Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

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

    public function image()
    {
      return $this->morphOne('App\Image', 'imageable');
    }
}

User.php

<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;


class User extends Authenticatable
{
    use Notifiable;
    protected $fillable = [
        'name', 'country_id',
    ];
    public function image()
  {
      return $this->morphOne('App\Image', 'imageable');
   }
}
 

Images.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
    protected $fillable = [
        'url', 'imageable_id','imageable_type'
    ];     
    
     public function imageable()
    {
        return $this->morphTo();
     }
}
 

4.Create route and controller to access data.

Route in Web.php

Route::get('onetoonepoly','PolyController@onetoonepoly');
 

Create PolyController.php using below command in command prompt.

php artisan make:controller PolyController
 

Implement code in PolyController.php as below

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;
use App\Image;
use App\Post;

class PolyController extends Controller
{
    //
    public function onetoonepoly()
    {
       $post = App\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\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:

public function imageable()
{
    return $this->morphTo(__FUNCTION__, 'imageable_type', 'imageable_id');
}

Related Post