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
.
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');
}