Is there a simple way to determine if a model is part of a polymorphic relationship?
I have to merge models as well as all of their related models. The process is somewhat different for a polymorphic relationship than it is for a traditional one-to-many or many-to-many relationship.
Let's suppose I have two models. Banner
is polymorphic but Appointment
is not.
class Banner extends Model
{
public function bannerable(): MorphTo
{
return $this->morphTo();
}
}
class Appointment extends Model
{
public function provider(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
I tried looking at the morphType
and also looking to see if the method exists on the class, but no luck.
> (new Banner)->morphTo()->getMorphType()
= "eval_type"
> (new Appointment)->morphTo()->getMorphType()
= "eval_type"
> method_exists(Banner::class, 'morphTo')
= true
> method_exists(Appointment::class, 'morphTo')
= true
You could use Reflection
on the model classes, and then check if they have any method that returns a polymorphic relation type (MorphTo
, MorphOne
, MorphMany
, etc).
This is what it looks like.
use App\Models\Appointment;
use App\Models\Banner;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use ReflectionClass;
use ReflectionMethod;
$is_appointment_model_polymorphic = collect((new ReflectionClass(Appointment::class))->getMethods())
->where('class', Appointment::class) // discard methods that are declared in the parent class, such as morphTo()
->filter(function (ReflectionMethod $rm): bool {
$returnType = $rm->getReturnType()->getName();
return $returnThype === MorphTo::class
// or return in_array($returnType, [MorphTo::class, ... ]
})
->isNotEmpty();