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

Laravel如何反转关联输出 获取指定结构的最近仓库关联产品数据

解决方案

前置优化:先查询最近仓库ID(性能优化)

先单独查询最近的仓库ID,避免嵌套在闭包中重复查询,同时提前处理无仓库的异常场景:

// 提取最近仓库ID
$nearestWarehouseId = Warehouse::orderByDistance('location', new Point($req->query('lat'), $req->query('lng')))
    ->value('id');

if (!$nearestWarehouseId) {
    // 无匹配仓库时自行处理返回逻辑
    return response()->json([]);
}

方案1:无需改模型,直接用集合整理输出结构(最简方案)

不需要调整现有模型关联,直接对查询结果做集合格式化,就能得到你要的结构:

$products = Product::whereHas('warehouses', static function ($q) use ($nearestWarehouseId) {
        $q->where('warehouses.id', $nearestWarehouseId);
    })
    ->with('feature_values.feature')
    ->paginate()
    // 遍历分页数据整理结构
    ->through(function ($product) {
        // 按特征分组当前产品的所有特征值
        $groupedFeatures = $product->feature_values->groupBy('feature_id')->map(function ($featureValues) {
            $feature = $featureValues->first()->feature;
            return [
                'id' => $feature->id,
                'name' => $feature->name,
                'feature_values' => $featureValues->map(fn($v) => [
                    'id' => $v->id,
                    'value' => $v->value
                ])
            ];
        })->values();
        
        // 替换关联结构
        unset($product->feature_values);
        $product->features = $groupedFeatures;
        return $product;
    });

方案2:通过API资源标准化输出(更推荐,可维护性高)

如果需要长期维护这个输出结构,用Laravel自带的API资源做格式管控更稳妥:

  1. 生成对应资源类
php artisan make:resource ProductResource
php artisan make:resource FeatureResource
php artisan make:resource FeatureValueResource
  1. 编辑app/Http/Resources/FeatureValueResource.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'value' => $this->value
    ];
}
  1. 编辑app/Http/Resources/FeatureResource.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'feature_values' => FeatureValueResource::collection($this->feature_values)
    ];
}
  1. 编辑app/Http/Resources/ProductResource.php
public function toArray($request)
{
    // 先按特征分组特征值
    $groupedFeatures = $this->feature_values->groupBy('feature_id')->map(function ($values) {
        return new FeatureResource($values->first()->feature->setRelation('feature_values', $values));
    })->values();

    return [
        'id' => $this->id,
        'name' => $this->name,
        'price' => $this->price,
        'features' => $groupedFeatures
    ];
}
  1. 控制器最终返回
$products = Product::whereHas('warehouses', static function ($q) use ($nearestWarehouseId) {
        $q->where('warehouses.id', $nearestWarehouseId);
    })
    ->with('feature_values.feature')
    ->paginate();

return ProductResource::collection($products);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:06:07