There's an exciting undocumented feature in Laravel that was introduced in 5.1 called morphMap
. The Morph Map is an extension of the polymorphic relationships and an effort to make them easier to use. If you used them in pre-5.1, you'd see a record like this:
[
"id" => 1,
"comment" => "Hello world",
"commentable_type" => "App\Models\Post",
"commentable_id" => 5
]
The commentable_type
included the full namespace for the associated record type, which had a few downsides:
If that namespace changes, you had to write a migration to change all the instances in your database
Long namespaces (such as App\Models\Customers\Projects\Bids\BidInvitation
) means that you have to set a long max length on the column
It's difficult to remember the full namespace
It's best practice if the client doesn't know full namespaces
This was thankfully addressed via pull request #9891, which added the Relation::morphMap()
method. That method defines a mapping of names to class paths globally. You do this with:
Relation::morphMap([
'post' => App\Models\Post::class,
'video' => App\Models\Video::class,
'user' => App\Models\User::class,
]);
That will allow you to use post
instead of App\Models\Post
in your database and will automatically map it when setting up the relationships within your Eloquent model. The best place to define that is in a service provider; I recently called it in AppServiceProvider
. So now, you would instead add this record
[
"id" => 1,
"comment" => "Hello world",
"commentable_type" => "post",
"commentable_id" => 5
]
and it would behave in the exact same manner as the previous example does. This feature is completely undocumented right now with no clear indication why. I highly recommend using it and avoid writing your own implementation as we were forced to do on a 5.0 project.