PHP
Managing Diverse Related Models with Polymorphic Relationships
Learn to implement Laravel Eloquent polymorphic relationships for models that can belong to multiple different types of parent models, simplifying data structures and queries.
// app/Models/Image.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
protected $fillable = ['url', 'imageable_id', 'imageable_type'];
public function imageable()
{
return $this->morphTo();
}
}
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['title', 'content'];
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// Usage example (e.g., in a controller or seeder)
$post = Post::find(1);
$post->images()->create(['url' => 'http://example.com/post-image.jpg']);
$user = User::find(1);
$user->images()->create(['url' => 'http://example.com/user-avatar.png']);
// Retrieve images
$postImages = $post->images; // Collection of Image models
$userImages = $user->images; // Collection of Image models
// Access parent from image
$image = Image::find(1);
$imageable = $image->imageable; // This could be a Post or a User model
How it works: Polymorphic relationships allow a model to belong to more than one other model on a single association. For instance, an `Image` model can belong to either a `Post` or a `User`. The `morphTo()` method defines the inverse of the polymorphic relationship on the `Image` model, while `morphMany()` (or `morphOne()`) defines the relationship on the `Post` and `User` models, specifying the `imageable` name. Laravel automatically handles storing the type and ID of the parent model in the `imageable_type` and `imageable_id` columns respectively on the `images` table.