通过 Laravel API 为分组集合输出数据

Data output via the Laravel API for a grouped collection

提问人:Kastorsky 提问时间:11/15/2023 最后编辑:Brian Tompsett - 汤莱恩Kastorsky 更新时间:11/17/2023 访问量:47

问:

我的问题是我无法带来按类别分组的产品列表的输出,以便在使用 Decodable 协议的 iOS 应用程序中进一步反序列化。

在我的 Laravel 10 应用程序中,有 3 个实体:购物车、产品和类别,它们之间建立了关系,一个类别可以包含许多产品,并且一个产品有一个类别,这部分有效。

当我拿到购物篮中的必要产品时:

$collection = DB::table('cart_product')
    ->where('cart_id', $validRequest['cart_id'])
    ->join('products', 'cart_product.product_id', '=', 'products.id')
    ->join('categories', 'products.category_id', '=', 'categories.id')
    ->select('categories.name as category', 'cart_product.id', 'products.name as product', 'cart_product.count')
    ->get();

return $collection;

我得到以下输出:

[
  {
    "category": "Plumbing",
    "id": 2,
    "product": "Sink",
    "count": "1.00"
  },
  {
    "category": "Dairy products",
    "id": 1,
    "product": "Milk",
    "count": "2.00",
  },
  {
    "category": "Dairy products",
    "id": 5,
    "product": "Yogurt",
    "count": "4.00",
  }
]

将分组方法应用于 groupBy 集合后,我得到一个分组集合:return $collection->groupBy('category');

{
  "Plumbing": [
    {
      "category": "Plumbing",
      "id": 2,
      "product": "Sink",
      "count": "1.00"
    }
  ],
  "Dairy products": [
    {
      "category": "Dairy products",
      "id": 1,
      "product": "Milk",
      "count": "2.00",
    },
    {
      "category": "Dairy products",
      "id": 5,
      "product": "Yogurt",
      "count": "4.00",
    }
  ]
}

但是为了响应请求,我需要提供带有静态键的数据,将来应该在消费者应用程序中正确反序列化,即对应以下示例:

[
  {
    "category": "Plumbing",
    "products": [
      {
        "id": 2,
        "product": "Sink",
        "count": "1.00"
      }
    ]
  },
  {
    "category": "Dairy products",
    "products": [
      {
        "id": 1,
        "product": "Milk",
        "count": "2.00",
      },
      {
        "id": 5,
        "product": "Yogurt",
        "count": "4.00",
      }
    ]
  }
]

我尝试了官方文档中关于使用集合(group By、group +、、)的各种示例,尝试在资源和集合处理程序中执行此处理,但我无法以正确的格式获得数据输出,Google也没有为我的问题提供相关答案。By()map()mapWithKeys()mapToGroups()

我寻求帮助来解决问题。

Laravel Collections 响应 可编码

评论


答:

0赞 Lalit Kumar 11/15/2023 #1

试试这个可能会对你有所帮助

$collection = DB::table('cart_product')
    ->where('cart_id', $validRequest['cart_id'])
    ->join('products', 'cart_product.product_id', '=', 'products.id')
    ->join('categories', 'products.category_id', '=', 'categories.id')
    ->select('categories.name as category', 'cart_product.id', 'products.name as product', 'cart_product.count')
    ->get();

$collection = $collection->groupBy('category')->map(function ($item, $key) {
    return [
        'category' => $key,
        'products' => $item->map(function ($product) {
            return [
                'id' => $product->id,
                'product' => $product->product,
                'count' => $product->count
            ];
        })->values()
    ];
})->values();

          

评论

1赞 Kastorsky 11/15/2023
这是关于魔术 values() 方法,它删除了原始键,我为此苦苦挣扎。非常感谢,一切正常。
0赞 Bilal Saad 11/15/2023 #2

若要解决此问题,请执行以下代码:

$cartData = Cart::with('products.category')->get();
    
    $result = [];
    
    foreach ($cartData as $cart) {
        $result[] = [
            'category' => $cart->products->first()->category->name,
            'products' => $cart->products->map(function ($product) {
                return [
                    'id' => $product->id,
                    'product' => $product->name,
                    'count' => $product->pivot->count,
                ];
            })->toArray(),
        ];
    }
    
    // Convert the result to JSON
    $jsonResult = json_encode($result, JSON_PRETTY_PRINT);
    
    // Output or return the JSON result
    echo $jsonResult;

评论

0赞 Kastorsky 11/15/2023
谢谢,您的选择完全适用于 Eloquent ORM 方法,特别是在此请求中,我使用了 Laravel DB 外观。我一定会用它来做雄辩的门面。