I'm available to work on new projects starting July 2020! Get in touch!
A new undocumented feature in laravel 5.2 was introduced: The Morph Map for morphTo relations.
We all know the polymorphic relations, they are a type of relation to link multiple models with one common model. For instance if you have a User and a Blog Post model, both of these can have a "Picture" relationship.
From the documentation:
Polymorphic relations allow a model to belong to more than one other model on a single association. For example, imagine users of your application can "like" both posts and comments. Using polymorphic relationships, you can use a single likes table for both of these scenarios.
Let's use the example from the documentation:
posts
id - integer
name - string
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
You can see here, both videos
and posts
can have tags
associated with them. In laravel 5.1 the contents of taggables
table looked something like this:
| tag_id | taggable_id | taggable_type |
| ------------- |-----------------------| ---------------------|
| 1 | 1 | App\Models\Post |
| 2 | 1 | App\Models\Post |
| 1 | 1 | App\Models\Video |
This is very nice and was extremely usefull in certain situations.
However there is one big flaw with this. What if... the namespace of the Post
model changes ?
Yep indeed, you will have to make some sort of migration to rename all occurences in the taggables
table. Not very nice is it ?
In laravel 5.2, morphMap
came to the resque of this "issue".
You can with this feature define a map of classes that will be used in the morphTo
type relations. In our example this can be:
Relation::morphMap([
'post' => \App\Models\Post::class,
'video' => \App\Models\Video::class,
]);
Now when you save a new morphTo relationship, instead of having the full namespace in the taggable_type
column, you will have the key name of the map.
| tag_id | taggable_id | taggable_type |
| ------------- |-----------------------| ---------------------|
| 1 | 1 | post |
| 2 | 1 | post |
| 1 | 1 | video |
You can now safely and easily refactor the namespace of the Post
model, without having to change the data in the database table.
Further details can be found in the laravel test suite. This is a good example of why many say the tests are documentation!
Edit: It seems to be already available in laravel 5.1, added since pull request 10141
I'm available to work on new projects starting July 2020! Get in touch!
Deploy your projects with zero downtime Laravel: Validate login and register forms on the same view