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

Laravel中如何预加载多态关联关系?

Laravel 嵌套关联预加载失效问题解决

模型关联定义

Device.php 模型

/**
 * 获取与设备直接关联的所有天线
 *
 * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 */
public function antennas() : MorphMany
{
    return $this->morphMany(Antenna::class, 'attachable');
}

/**
 * 获取设备的所有固定阅读器
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function fixedReaders() : HasMany
{
    return $this->hasMany(FixedReader::class);
}

FixedReader.php 模型

/**
 * 获取阅读器的所有天线
 *
 * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 */
public function antennas() : MorphMany
{
    return $this->morphMany(Antenna::class, 'attachable');
}

Antenna.php 模型

/**
 * 获取所属的父模型(设备或固定阅读器)
 */
public function attachable(): MorphTo
{
    return $this->morphTo();
}

问题描述

查询Device模型时,尝试预加载fixedReaders的嵌套关联antennas,以及设备自身的antennas,使用以下代码但未生效:

Device::select('devices.*')
        ->with([
            'fixedReaders' => [
                'antennas'
            ],
            'antennas',
        ])
        ->get();

解决方案

1. 修正预加载写法

Laravel提供两种标准的嵌套关联预加载写法,可替换原代码:

写法一:点语法(简洁版)

Device::select('devices.*')
    ->with('fixedReaders.antennas', 'antennas')
    ->get();

写法二:闭包嵌套(灵活版)

若需要对fixedReaders添加额外查询条件,可使用闭包:

Device::select('devices.*')
    ->with([
        'fixedReaders' => function ($query) {
            // 可添加额外条件,如筛选状态
            // $query->where('status', 1);
            $query->with('antennas');
        },
        'antennas'
    ])
    ->get();

2. 排查关联基础配置

若修正写法后仍无效果,需确认以下配置:

  • fixed_readers表存在device_id字段,且与devices.id字段类型匹配;
  • antennas表存在attachable_id(整数型)和attachable_type(字符串型)字段,attachable_type需准确对应模型的完整类名(如App\Models\Device);
  • 数据库中存在对应的关联数据,避免因无数据导致预加载结果为空。

内容的提问来源于stack exchange,提问作者Anshul Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:13:21