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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs