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

Laravel四层嵌套hasmany关联在最下级子模型加where条件返回正向嵌套JSON

解决方案

修正后完整实现代码

以下是ModelA中thedata静态方法的正确实现,可同时满足末级筛选、正向嵌套结构返回、父级指定字段查询需求:

public static function thedata($string)
{ 
    return self::whereHas('modelb.modelc.modeld', function ($query) use ($string) {
        // 筛选存在符合条件ModelD的顶层ModelA
        $query->where('column', 'like', "%{$string}%")
            ->whereColumn('modelc.column2', 'modeld.column2')
            ->whereColumn('modelc.column3', 'modeld.column3');
    })
    ->with([
        // 指定ModelB返回字段,必须带主键id和关联父级的外键modela_id
        'modelb:id,modela_id,field1,field2',
        // 指定ModelC返回字段,必须带主键id和关联父级的外键modelb_id
        'modelb.modelc:id,modelb_id,column2,column3,field1',
        // 过滤末级ModelD,指定返回字段需带关联父级的外键modelc_id
        'modelb.modelc.modeld' => function ($query) use ($string) {
            $query->where('column', 'like', "%{$string}%");
        }
    ])
    ->get();
}

关联定义优化建议

建议将ModelC和ModelD的跨表匹配条件放到关联方法中,避免重复编码:

// ModelC.php
public function modeld()
{
    return $this->hasMany(ModelD::class)
        ->whereColumn('modelc.column2', 'modeld.column2')
        ->whereColumn('modelc.column3', 'modeld.column3');
}

优化后thedata方法中的两个查询闭包都可以删除whereColumn相关代码,逻辑更简洁。

逻辑说明

  • whereHas('modelb.modelc.modeld')的作用是筛选顶层ModelA:仅保留子孙层级中存在符合筛选条件ModelD的顶层模型,过滤无匹配数据的父级记录
  • 带闭包的with预加载的作用:
    1. 按ModelA->ModelB->ModelC->ModelD的正向结构组装嵌套数据
    2. 仅返回符合筛选条件的末级ModelD,不会返回同层级下其他不符合条件的子记录
    3. 支持自定义各级关联返回的字段,注意每级字段必须包含自身主键和指向父级的外键,否则关联关系无法正常绑定

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:24:05