Laravel中如何按需预加载多态关联的不同嵌套关联?
解决Laravel多态关联中按需加载嵌套关联的问题
我完全懂你碰到的这个坑——你的Review模型用了多态关联,能关联Estimate或者EventDate,但这俩模型关联Event的路径完全不一样,直接用with同时塞两个嵌套关联进去,肯定会报错,因为某类模型根本没有对应的关联方法嘛。
问题根源
你一开始试的User::with([ 'reviews.reviewable.event', 'reviews.reviewable.ask_estimate.event' ])->get();,Laravel会傻乎乎地给所有reviewable模型都尝试加载event和ask_estimate关联,但EventDate哪来的ask_estimate?Estimate又没有event关联,这不报错才怪。
正确解决方案
Laravel其实专门提供了处理这种场景的方法——loadMorph(或者withMorph),它能针对不同的多态模型类型,按需加载对应的嵌套关联。
从Review模型出发查询
你可以直接查询指定用户的Review,然后用loadMorph来精准加载关联:
$userReviews = Review::where('user_id', $user->id) ->with('reviewable') ->loadMorph('reviewable', [ Estimate::class => ['ask_estimate.event'], EventDate::class => ['event'], ]) ->get();
这段代码的逻辑很清晰:
- 先筛选出当前用户的所有Review
- 预加载基础的
reviewable多态关联 - 通过
loadMorph指定:- 如果
reviewable是Estimate类型,就加载它的ask_estimate关联,再嵌套加载ask_estimate下的event - 如果
reviewable是EventDate类型,直接加载它的event关联
- 如果
这样Laravel就不会乱加载不存在的关联,自然就不会抛出异常了。
从User模型出发查询
如果你想直接从User模型入手查询,也可以用withMorph嵌套在闭包里:
$user = User::with(['reviews' => function ($query) { $query->withMorph('reviewable', [ Estimate::class => ['ask_estimate.event'], EventDate::class => ['event'], ]); }])->find($user->id);
这样获取到的$user对象里,所有的reviews都会带着正确的嵌套event关联。
内容的提问来源于stack exchange,提问作者Elie Boury
相关产品推荐
相关产品推荐

