[5.6] Allow eager-loading mixed relationships of polymorphic collection#23626
Conversation
|
We don't support eager loading morphTo relationships already? I see the code in the framework to support it? |
|
This is allowing eager-loading from mixed classes that have relationships uncommon between each other. From the above example: $activities = ActivityFeed::with([
'parentable.calendar', // Event@calendar() hasOne
'parentable.tags', // Photo@tags() hasMany, relation doesn't exist in Event class
'parentable.author', // Post@author() hasOne
'parentable.commentsCount', // Post@commentsCount hasOne
])
->get();
I didn't see anything on https://laravel.com/docs/5.6/eloquent-relationships#eager-loading or in the source code that supports such eager loading? |
|
Gotcha. |
|
I'm fine if you want to add the paginator helper to this PR so I can review it all at once. |
046e004 to
3fbd5e7
Compare
Allow nested relations to be eager loaded for
morphTo() relationships of mixed classes.
e.g.,
class ActivityFeed
{
function parentable()
{
return $this->morphTo();
}
}
$collection = ActivityFeed::with('parentable')
->get()
->loadMorph('parentable', [
Event::class => 'calendar',
Photo::class => 'tags',
Post::class => ['author', 'commentsCount'],
]);
or
$paginator = ActivityFeed::with('parentable')
->paginate()
->loadMorph('parentable', [
// etc.
]);
3fbd5e7 to
4367675
Compare
|
@derekmd is there any plan to work on your "ideal world" (which is amazing btw)? This problem does not encourage developers to use polymorphic relation. :( I have to process hundreds of polymorphic records and play with nested relations and the overload of queries is a nightmare. Best |
I've had this macro kicking around for awhile since the framework doesn't offer a way to avoid N+1 queries from
morphTo()nested relationships. This addsIlluminate\Database\Eloquent\Collection@loadMorph()to allow nested eager loading by naming the unique relationship(s) for each class name.Issue reported:
External Laravel community:
Example Use Case
In an ideal world...
...this would be supported:
I really wanted to work this into the existing eager-load infrastructure:
Illuminate\Database\Eloquent\Builder@with()Illuminate\Database\Eloquent\Collection@load()Illuminate\Database\Eloquent\Model@with(array object property)However this is going to require a significant rewrite of the Eloquent internals that store an associative array of query constraint
Closures.Pagination
For better developer experience in controllers, an explicit
AbstractPaginator@loadMorph()proxy is added to return the paginator. This allows it to be passed into the view or returned by an API response.Then controllers don't have to awkwardly do:
but: