How To Define Custom Polymorphic Types With Laravel Framework

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.today we are going to discuss how to Custom Polymorphic Types in laravel

How To Define Custom Polymorphic Types With Laravel Framework

Define Custom Polymorphic Types With Laravel 

Lets start.
How to Define  Custom Polymorphic Types


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

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


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

Now we need to create Posts,Video and  Comment models in fresh project so for that run below commands in comand prompt.

php artisan make:model Post -m

php artisan make:model Video -m

php artisan make:model Comment -m

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

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('title');
            $table->text('body');
            $table->timestamps();
        });
    }

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

2020_09_07_132636_create_videos_table.php

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateVideosTable extends Migration
{
    public function up()
    {
        Schema::create('videos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('url');
            $table->timestamps();
        });
    }

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

2020_09_07_132747_create_comments_table.php

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommentsTable extends Migration
{

    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->text('body');
            $table->integer('commentable_id');
            $table->string('commentable_type');
            $table->timestamps();
        });
    }

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


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', 'body '
    ];

    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}


Videos.php

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{

    protected $fillable = [
        'title', 'url'
    ];

    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}


Comments.php

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $fillable = [
        'body', 'commentable_id', 'commentable_type'
    ];

    public function commentable()
    {
        return $this->morphTo();
    }
}

You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to morphTo. In our case, that is the commentable method on the Comment model. So, we will access that method as a dynamic property:

$comment = App\Comment::find(1);

$commentable = $comment->commentable;

The commentable relation on the Comment model will return either a Post or Video instance, depending on which type of model owns the comment.

Custom Polymorphic Types

By default, Laravel will use the fully qualified class name to store the type of the related model. For instance, given the one-to-many example above where a Comment may belong to a Post or a Video, the default commentable_type would be either App\Post or App\Video, respectively. However, you may wish to decouple your database from your application's internal structure. In that case, you may define a "morph map" to instruct Eloquent to use a custom name for each model instead of the class name:

Add this in post model and access the variable names in controller
 

use Illuminate\Database\Eloquent\Relations\Relation;

Relation::morphMap([
    'posts' => 'App\Post',
    'videos' => 'App\Video',
]);


You may determine the morph alias of a given model at runtime using the getMorphClass method. Conversely, you may determine the fully-qualified class name associated with a morph alias using the Relation::getMorphedModel method:

use Illuminate\Database\Eloquent\Relations\Relation;

$alias = $post->getMorphClass();

$class = Relation::getMorphedModel($alias);


Note:When adding a "morph map" to your existing application, every morphable *_type column value in your database that still contains a fully-qualified class will need to be converted to its "map" name.

Related Post