I'm trying to get all the Reviews of a User, with their Event. I have a polymorphic relationship in Review: it can be linked to either an Estimate or an EventDate. EventDate is directly linked to Event, but Estimate is linked to it through AskEstimate.
I'd like to do this :
User::with([
'reviews.reviewable.event',
'reviews.reviewable.ask_estimate.event'
])->get();
But of course it throws an exception: when reviewable is an EventDate, it doesn't have any AskEstimate relation and when it is an Estimate, it doesn't have any Event relation.
So how can I get something giving me either one or the other, according to the reviewable value?
Thanks!
EDIT:
Here is a working version.
Review::where('user_id', $user->id)
->with([
'reviewable',
])
->loadMorph('reviewable', [
Estimate::class => ['ask_estimate'],
EventDate::class => ['event'],
]);
It's been quite a while since this question was asked, and it hasn't been answered correctly yet. Here's the proper way to handle eager loading of nested relationships in polymorphic relationships, based on the current Laravel documentation.
The best approach is to use the morphTo
relationship's morphWith
method in combination with with
. This allows you to specify the nested relationships for each type of polymorphic relationship.
Here’s how you can achieve what you're looking for:
use Illuminate\Database\Eloquent\Relations\MorphTo;
// Assuming you want to eager load 'reviews.reviewable.event' or 'reviews.reviewable.ask_estimate.event' dynamically:
$users = User::query()
->with(['reviews.reviewable' => function (MorphTo $morphTo) {
$morphTo->morphWith([
EventDate::class => ['event'], // If reviewable is EventDate, load its 'event'
Estimate::class => ['ask_estimate.event'], // If reviewable is Estimate, load its 'ask_estimate.event'
]);
}])->get();
Polymorphic Relationship (morphTo
): The reviewable
relationship is a polymorphic relationship, so we use morphTo
to handle the relationship dynamically.
morphWith
: The morphWith
method specifies the nested relationships for each possible type of reviewable
. For example:
reviewable
is an EventDate
, we load its event
.reviewable
is an Estimate
, we load its ask_estimate
and the nested event
.Avoid Exceptions: Using morphWith ensures that Laravel dynamically loads the appropriate nested relationships for the correct type of reviewable, avoiding the exceptions you encountered.
This approach is clean, follows the current best practices, and ensures that your polymorphic relationships are eager loaded efficiently.