📣 Shoutout to Ankur Kumar who wrote the original code for this relation in their package Eloquent Relations. I created this package as I needed to make a few tweaks to suit my needs. 🙌
You can install the package via composer:
composer require fidum/laravel-eloquent-morph-to-one
The MorphToOne
relation is uses Laravel's MorphToMany under the hood. However, the difference is that it returns one model instead of a Collection
of models.
If there is no related model in the database it will return null
where MorphToMany
would return an empty Collection
.
Example:
<?php
namespace App;
use Fidum\EloquentMorphToOne\HasMorphToOne;
use Fidum\EloquentMorphToOne\MorphToOne;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
class Post extends Model
{
use HasMorphToOne;
public function featuredImage(): MorphToOne
{
return $this->morphToOne(Image::class, 'imageable')
->wherePivot('featured', 1);
//->withDefault();
}
public function images(): MorphToMany
{
return $this->morphToMany(Image::class, 'imageable')
->withPivot('featured');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
class Image extends Model
{
public function posts(): MorphToMany
{
return $this->morphedByMany(Post::class, 'imageable');
}
public function videos(): MorphToMany
{
return $this->morphedByMany(Video::class, 'imageable');
}
}
Now you can access the relationship like:
<?php
// eager loading
$post = Post::with('featuredImage')->first();
dump($post->featuredImage);
// lazy loading
$post->load('featuredImage');
Prefer using sync
instead of save
when updating your relation.
$post->featuredImage()->sync([Image::find(123)]);
$post->featuredImage()->sync([Image::find(456)]);
$post->images->count(); // 1 row :)
❌ DO NOT use save
it will follow morphToMany
behaviour and create rather than update existing.
$post->featuredImage()->save(Image::find(123));
$post->featuredImage()->save(Image::find(456));
$post->images->count(); // 2 rows :(
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security related issues, please email fidum.dev@gmail.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.