PHP
Implementing and Querying Polymorphic Relationships in Laravel Eloquent
Discover how to use Laravel Eloquent's polymorphic relationships, allowing a model to belong to more than one other model on a single association.
// Example Models:
// app/Models/Image.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class Image extends Model
{
protected $fillable = ['url', 'imageable_id', 'imageable_type'];
public function imageable(): MorphTo
{
return $this->morphTo();
}
}
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class Post extends Model
{
protected $fillable = ['title', 'content'];
public function images(): MorphMany
{
return $this->morphMany(Image::class, 'imageable');
}
}
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class User extends Model
{
protected $fillable = ['name', 'email'];
public function profileImages(): MorphMany
{
return $this->morphMany(Image::class, 'imageable');
}
}
// Usage example:
use App\Models\User;
use App\Models\Post;
use App\Models\Image;
// Create a user and attach an image
$user = User::create(['name' => 'Jane Doe', 'email' => '[email protected]']);
$user->profileImages()->create(['url' => 'https://example.com/jane_avatar.jpg']);
// Create a post and attach multiple images
$post = Post::create(['title' => 'My First Post', 'content' => 'Lorem ipsum...']);
$post->images()->createMany([
['url' => 'https://example.com/post1_img1.jpg'],
['url' => 'https://example.com/post1_img2.jpg']
]);
// Retrieve images for a specific user
$userImages = User::find($user->id)->profileImages;
foreach ($userImages as $image) {
echo "User Image URL: " . $image->url . "
"; // Output: https://example.com/jane_avatar.jpg
}
// Retrieve images for a specific post
$postImages = Post::find($post->id)->images;
foreach ($postImages as $image) {
echo "Post Image URL: " . $image->url . "
"; // Output: ...post1_img1.jpg, ...post1_img2.jpg
}
// Accessing the parent model from an image
$someImage = Image::first();
if ($someImage) {
echo "Image belongs to: " . ($someImage->imageable->name ?? $someImage->imageable->title) . "
";
echo "Imageable Type: " . $someImage->imageable_type . "
"; // Output: App\Models\User or App\Models\Post
}
How it works: Polymorphic relationships in Laravel Eloquent allow a model to belong to more than one other model using a single association. In this example, the `Image` model can belong to either a `User` or a `Post` via the `imageable` relationship. The `imageable_id` and `imageable_type` columns in the `images` table store the ID of the related model and its class name, respectively. This enables flexible and efficient association of images with various content types.