36864's avatar
Level 13

Getting Model's morph class without an instance

When using a custom morphMap, you can get the morph class for a model using the getMorphClass() instance method. The inverse operation can be found in a static method in the Model class, getActualClassNameForMorph()

Is there a static way to get the result of getMorphClass()? I can get it by creating an instance of the model, but that's not very nice. Using the morphMap array directly also doesn't feel right.

Ideally, I'd like to do something like this:

function morph_name($morphableType){
 return $$morphableType::getMorphClass();
}

which would work as this currently does:

function morph_name($morphableType){
 return (new $morphableType)->getMorphClass();
}

I've looked through the API docs and can't find any method that does this.

0 likes
6 replies
staudenmeir's avatar

There is no static method for this. Use return (new $morphableType)->getMorphClass();.

6 likes
gizmojo's avatar
/**
     * Retrieve the actual class name for a given morph class.
     *
     * @param  string  $class
     * @return string
     */
    public static function getActualClassNameForMorph($class)
    {
        return Arr::get(Relation::morphMap() ?: [], $class, $class);
    }

$morphName =  Model::getActualClassNameForMorph($className);
raphael's avatar

@gizmojo That doesn't work for me. It returns 'Supplier' although in the Relation Morph Map the Supplier::class is set to 'supplier'.

Emile Bourquin's avatar
function morph_name($morphableType){
 return array_search($morphableType, Relation::$morphMap);
}
1 like
IronSinew's avatar
if (! function_exists('morph_name')) {
    /**
     * Get the morph name for a class or return same class name without a morph value
     *
     * @param  string  $morphableType  Class name to look for
     */
    function morph_name(string $morphableType): string
    {
        return array_search($morphableType, Relation::$morphMap) ?: $morphableType;
    }
}

Usage would be: morph_name(\App\Models\User::class); .. it will either return the name of the morph mapping value if present, or return the same string passed in. This should allow it to always be "safe" to compare against a possible morph map value, unless you're using enforceMorphMap in which case it'd throw an exception before this anyway.

1 like

Please or to participate in this conversation.