Laravel如何避免加载多态关联模型中$with定义的默认关联?
问题描述
我执行了如下查询:
$users = User::query()->with(['relation'])->get();
User模型中定义了如下多态关联:
public function relation(): MorphTo { return $this->morphTo(__FUNCTION__, 'object_type', 'object_id'); }
由于这是多态关联,执行$users->first()->relation可能返回不同的模型,而这些模型都设置了默认预加载:
class Book extends Model { protected $with = ['authors', 'publications']; } class Magazine extends Model { protected $with = ['shops']; }
请问如何避免加载这些在各模型的protected $with = [];中定义的关联?
解决方案
可以通过以下几种方式取消这些默认预加载:
1. 统一排除所有默认关联
在预加载多态关联时,直接调用without方法排除所有可能的默认预加载项:
$users = User::query() ->with(['relation' => function ($query) { $query->without(['authors', 'publications', 'shops']); }]) ->get();
不管关联的是Book还是Magazine,都会去掉它们的默认预加载关联,操作简单直接。
2. 按模型类型精准排除
如果需要针对不同模型做不同处理,可以在闭包中判断模型类型,针对性排除:
use App\Models\Book; use App\Models\Magazine; $users = User::query() ->with(['relation' => function ($query) { $query->whenInstanceOf(Book::class, function ($q) { $q->without(['authors', 'publications']); })->whenInstanceOf(Magazine::class, function ($q) { $q->without(['shops']); }); }]) ->get();
这种方式能更灵活地控制不同模型的预加载行为,适合需要差异化处理的场景。
3. 直接清空模型默认预加载配置
通过setEagerLoads方法直接将关联模型的默认预加载数组置空,彻底取消所有默认预加载:
$users = User::query() ->with(['relation' => function ($query) { $query->getModel()->setEagerLoads([]); }]) ->get();
这个方法不需要提前知道具体的默认关联项,适合不确定所有模型默认预加载内容的场景。
内容的提问来源于stack exchange,提问作者Roman Slisarenko
相关产品推荐
相关产品推荐

