Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

fenos's avatar

MorphClass Property in eloquent Model

Hi guys, I'm working with polymorphic relations and I found the $moprhClass Property to be useful to short the name of the class when stored on the DB. example: Acme\Book -> Book

Inserting the data it works and it insert the short name as expected. But When I need to fetch the polymorphic data with an eager loading relation, It try to find the class stored as the short name of it, for this reason an Class Not Found Exception is thrown.

Example:

namespace Acme;

class Book extends Eloquent {

     protected $morphClass = 'Book';

     public function bookable() {

           return $this->morphTo();
     }
}

// Another file
namespace Acme\User;
class User extends Eloquent {

      public function books() {
          return $this->morphMany('Acme\Book','bookable');
      }
}

Getting result

User::with('books')->get();

This throw the exception: Class Book not Found Exception

What's the benefit to use $morphClass Property then?

0 likes
13 replies
bestmomo's avatar

Your are in the same namespace :

return $this->morphMany('Book','bookable');
fenos's avatar

Yhea , but i don't think is that the problem, My real classes are not on the same namespace, I change the namespace even in the examples for be more consistent.

bestmomo's avatar

If they are not in same namespace just set the good one ;)

thepsion5's avatar

What happens if you use the short name in your user relation? For example:

namespace Acme;
class User extends Eloquent {

      public function books()
     {
          return $this->morphMany('Book','bookable');
      }
}
1 like
fenos's avatar

@bestmomo I don't think that all the models should be under a same namespace, thanks anyway.

@thepsion5 It give me the same problem

2 likes
bestmomo's avatar

If you get Class Book not Found Exception that is because your namespace is wrong (check your namespaces) or your autoloader fails (try a dumpautoload).

thepsion5's avatar

Since it's not documented anywhere, it's entirely possible the $morphClass attribute is unfinished or doesn't work properly.

I looked through the source code where it gets used (Illuminate\Database\Eloquent\Relations\MorphOneOrMany and Illuminate\Database\Eloquent\Model if anyone is curious) and I can't figure out how it would work properly if the attribute is different from the fully namespaced class name.

fenos's avatar

@thepsion5 I did the exactly the same thing, and got the exactly your intuition. I know that $morphClass exists from the 4.1 but i discovered that not much time ago. But I'm a bit confused on the benefit and usage of it. :)

bestmomo's avatar

As I understand the code the benefit is null because it's resolved with the model name set as parameter.

1 like
fenos's avatar

It was really nice if we could use an 'alias' instead to store the full namespace of the class and the $morphClass I think was intended to do that. Will be nice to dig in to it a bit more

thepsion5's avatar

I'm not sure how well it would work in practice though. The model needs to somehow take the "short" alias and use it to find the full class name. I don't see how it could do that without doing something like scanning every class, checking to see if it extends from Eloquent, and then creating an instance of it and accessing the $morphClass property to see if it matches. Which would be crazy.

fenos's avatar

That's true :) thanks, but what about if i create a new configuration file called morph-aliases.php where i register each alias of my morphed model with it full namespace, then tweaking a bit the morph classes i can check if the $morphClass property and one alias match, if so, it pass the full namespace and work as expected. It just pass throw that file for check and retrieve an alias of the model.

you'll have all yours model aliases in a unique file.

it might be an idea?

lazychaser's avatar

Came across this issue, too. You just need to create aliases for your models in config/app.php.

Please or to participate in this conversation.