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

Laravel:如何扁平化多维预加载Eloquent集合

扁平化嵌套Eloquent集合(Region模型)

要实现按**父级→子级1→孙级1→孙级2→子级2……**的顺序扁平化嵌套的Region模型集合,且结果保持Eloquent集合类型,可以通过递归遍历的方式实现:

方法一:编写递归处理函数

创建一个辅助函数,递归遍历每个模型及其子级,按顺序收集所有模型:

function flattenRegions($regions) {
    $flattened = new Illuminate\Database\Eloquent\Collection();
    
    foreach ($regions as $region) {
        // 添加当前模型到结果集合
        $flattened->push($region);
        
        // 递归处理预加载的子级关联
        if ($region->relationLoaded('descendants') && $region->descendants->isNotEmpty()) {
            $flattened = $flattened->merge(flattenRegions($region->descendants));
        }
    }
    
    return $flattened;
}

// 使用示例
$originalCollection = // 你的嵌套Region集合
$flattenedCollection = flattenRegions($originalCollection);

方法二:在Region模型中添加实例方法

在Region模型内添加属性方法,直接返回自身及所有子级的扁平化集合:

// app/Models/Region.php
public function getFlattenedDescendantsAttribute() {
    $flattened = new \Illuminate\Database\Eloquent\Collection([$this]);
    
    if ($this->relationLoaded('descendants') && $this->descendants->isNotEmpty()) {
        foreach ($this->descendants as $descendant) {
            $flattened = $flattened->merge($descendant->flattened_descendants);
        }
    }
    
    return $flattened;
}

// 使用示例
// 单个根模型的扁平化
$flattenedFromRoot = $rootRegion->flattened_descendants;

// 根集合的扁平化
$flattenedCollection = new \Illuminate\Database\Eloquent\Collection();
$originalCollection->each(function ($region) use (&$flattenedCollection) {
    $flattenedCollection = $flattenedCollection->merge($region->flattened_descendants);
});

关键注意点

  • 确保descendants关联已通过with('descendants')预加载,避免触发N+1查询
  • 两种方法返回的都是Illuminate\Database\Eloquent\Collection实例,保留模型的Eloquent特性
  • 遍历顺序严格遵循父级优先、子级深度遍历的要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:00:02