PHP
Implementing Flexible Polymorphic Relationships with Laravel Eloquent
Discover how to build versatile one-to-many or many-to-many relationships where a model can belong to multiple other models on a single association.
<?php
// --- Models --- (Assuming Image, Post, User models exist)
// Image Model (app/Models/Image.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
protected $fillable = ['url'];
public function imageable()
{
return $this->morphTo();
}
}
// Post Model (app/Models/Post.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// User Model (app/Models/User.php)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// --- Usage --- (Assuming a Post and User with ID 1 exist)
// Create an image for a post
$post = App\Models\Post::find(1);
if ($post) {
$post->images()->create(['url' => 'post-image-1.jpg']);
}
// Create an image for a user
$user = App\Models\User::find(1);
if ($user) {
$user->images()->create(['url' => 'user-avatar.png']);
}
// Get images for a post
$postImages = App\Models\Post::find(1)->images;
// Get the parent of an image
$image = App\Models\Image::find(1);
$imageable = $image ? $image->imageable : null; // Returns either a Post or User model
How it works: Polymorphic relationships allow a model to belong to more than one other model on a single association. This is useful when a single model (e.g., `Image`, `Comment`, `Tag`) can be associated with multiple types of models (e.g., `Post`, `User`, `Product`). The `morphTo()` method is used on the 'child' model, while `morphMany()` (or `morphOne`, `morphToMany`) is used on the 'parent' models to define these flexible relationships, greatly reducing database schema complexity.