PHP
Implement Flexible Polymorphic Relationships in Laravel Eloquent
Understand how to define and query polymorphic relationships, allowing a single model to belong to multiple types of other models on a single association, enhancing database flexibility.
use Illuminate\Database\Eloquent\Model;
use App\Models\Post;
use App\Models\Video;
// In app/Models/Image.php
class Image extends Model
{
// Define the polymorphic relationship
public function imageable()
{
return $this->morphTo();
}
}
// In app/Models/Post.php
class Post extends Model
{
// Define the inverse polymorphic relationship
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// In app/Models/Video.php
class Video extends Model
{
// Define the inverse polymorphic relationship
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
// Usage Example
$post = Post::create(['title' => 'My Blog Post']);
$video = Video::create(['title' => 'My Awesome Video']);
$post->images()->create(['url' => 'post-image-1.jpg']);
$video->images()->create(['url' => 'video-thumbnail.png']);
// Retrieve images for a post
$postImages = $post->images; // Returns a collection of Image models
foreach ($postImages as $image) {
echo "Post Image: " . $image->url . "
";
}
// Retrieve the owner of an image (can be a Post or Video)
$image = Image::find(1);
$imageable = $image->imageable; // Returns a Post or Video model instance
if ($imageable instanceof Post) {
echo "Image belongs to Post: " . $imageable->title . "
";
} elseif ($imageable instanceof Video) {
echo "Image belongs to Video: " . $imageable->title . "
";
}
How it works: Polymorphic relationships allow a model to belong to more than one other model on a single association. For example, an `Image` model might belong to a `Post` model or a `Video` model. This is achieved by defining a `morphTo` method on the child model (`Image`) and `morphMany` or `morphOne` methods on the parent models (`Post`, `Video`). Eloquent automatically stores the type and ID of the associated model, providing incredible flexibility in your database schema without requiring separate relationship columns for each possible parent type.