You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:18:28