Laravel 5.5如何过滤数组嵌套对象并转为单个对象
解决Laravel 5.5关联过滤并将数组转为单个对象的问题
首先咱们来拆解下你现有代码的问题:
- 你用
with()的闭包确实能过滤price_role关联,但get()返回的是多个Product模型的集合,而且每个模型的price_role仍然是关联集合(对应JSON里的数组格式),哪怕只有一条匹配记录。 - 要得到单个对象而非数组,咱们需要额外处理关联格式,或者调整关联的定义方式。
下面给你两种可行的解决方案:
方案一:在模型中定义专属的hasOne关联(推荐)
如果经常需要按角色获取单个价格角色,直接在Product模型里新增一个hasOne类型的关联会更优雅:
// Product.php 模型文件 public function singlePriceRole($role) { return $this->hasOne(PriceRole::class)->where('role', $role); }
然后查询时直接调用这个关联,并且用first()获取单个Product模型(而非get()返回的集合):
$role = "HQ"; $product = Product::where('user_id', $user->id) ->with(['singlePriceRole' => function($q) use ($role) { $q->where('role', $role); }]) ->first();
这样返回的product->singlePriceRole就是单个对象,完全符合你想要的JSON格式。如果没有匹配的记录,它会返回null。
方案二:查询后手动转换关联格式
如果不想修改模型,可以在查询完成后,把每个Product的price_role集合转成单个对象:
$role = "HQ"; // 先执行原查询,获取过滤后的关联集合 $products = Product::with(['price_role' => function ($q) use ($role) { $q->where('role', '=', $role); }]) ->where('user_id', '=', $user->id) ->get(); // 遍历集合,把每个产品的price_role从数组转为单个对象 $products->transform(function($product) { // 取集合的第一个元素,无匹配则为null $product->price_role = $product->price_role->first(); return $product; });
如果只需要单个Product模型,把get()换成first(),直接处理单个模型的关联即可:
$product = Product::with(['price_role' => function ($q) use ($role) { $q->where('role', '=', $role); }]) ->where('user_id', '=', $user->id) ->first(); $product->price_role = $product->price_role->first();
这样处理后,返回的JSON里price_role就会是单个对象而非数组啦~
内容的提问来源于stack exchange,提问作者digit
相关产品推荐
相关产品推荐

