GroupBy вложил несколько уровней в Laravel - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть список вложенных многоуровневых объектов.Это из красноречивого запроса с отношением.

Место имеет много заказов

Заказ имеет много деталей и один клиент

У детали есть один продукт и один срок доставки

[
  {
    "place_id": 1,
    "name": "A Building",
    "address": "A Street, A Ward, A City",
    "orders": [
      {
        "customer": {
          "id": 1,
          "name": "Peter",
          "phone": "011111111"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 2,
          "name": "Mary",
          "phone": "022222222222"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 3,
            "product": {
              "name": "Glass of Milk Shake"
            }
          }
        ]  
      }

    ]
  },
  {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 3,
          "name": "Catherine",
          "phone": "0333333333"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 2,
            "product": {
              "name": "A Cup of Coffee"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 4,
          "name": "Tom",
          "phone": "04444444444444"
        },
        "order_details": [
          {
            "period_id": 2,
            "period": {
              "id": 1,
              "start_time": "10:00:00",
              "end_time": "10:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      }
    ]
  } 
]

Мне нужно сгруппировать этот список по "периоду", а затем по "месту"

Ожидаемый результат:

[ 
  {
    "id": 1,
    "start_time": "08:00:00",
    "end_time": "08:30:00",
    "places": [
    {
    "place_id": 1,
    "name": "A Building",
    "address": "A Street, A Ward, A City",
    "orders": [
      {
        "customer": {
          "id": 1,
          "name": "Peter",
          "phone": "011111111"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 2,
          "name": "Mary",
          "phone": "022222222222"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 3,
            "product": {
              "name": "Glass of Milk Shake"
            }
          }
        ]  
      }
    ]
  },
  {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 3,
          "name": "Catherine",
          "phone": "0333333333"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 2,
            "product": {
              "name": "A Cup of Coffee"
            }
          }
        ]  
      }
    ]
  } 
    ]
  },
   {
    "id": 2,
    "start_time": "10:00:00",
    "end_time": "10:30:00",
    "places": [
    {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 4,
          "name": "Tom",
          "phone": "04444444444444"
        },
        "order_details": [
          {
            "period_id": 2,
            "period": {
              "id": 1,
              "start_time": "10:00:00",
              "end_time": "10:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      }

    ]
  } 
    ]
  }
]

Вот мой подробный код:

class Place extends Model
{
    public function orderDetails()
    {
        return $this->hasManyThrough(OrderDetail::class, 
   Order::class,'place_id','order_id','id','id');
    }
}

class Period extends Model
{
    public function details()
    {
        return $this->hasMany(OrderDetail::class, 'period_id', 'id');
    }
}

class Order extends Model
{
    public function place()
    {
        return $this->belongsTo(Place::class, 'place_id', 'id');
    }

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function details()
    {
        return $this->hasMany(OrderDetail::class, 'order_id', 'id');
    }

}

class OrderDetail extends Model
{
    public function period()
    {
        return $this->belongsTo(Period::class, 'period_id', 'id');
    }

    public function product()
    {
        return $this->belongsTo(Product::class, 'product_id', 'id');
    }

    public function order()
    {
        return $this->belongsTo(Order::class, 'order_id', 'id');
    }
}


Place::with(['orderDetails', 'orderDetails.product', 'orderDetails.period', 'orderDetails.order.user'])->get()->toArray();

Я использую laravel, поэтому лучше воспользуйтесь помощником по сбору laravel, чтобы решить эту проблему быстрее.Пожалуйста, помогите мне .Спасибо

Обновлено:

Я использовал другой запрос и группу. В модели OrderDetail добавьте:

protected $appends = ['place_id'];
public function getPlaceIdAttribute()
{
  return $this->order->place_id;
}

Затем используйте этот запрос, я могу группировать период, а не только место.содержать идентификатор.

OrderDetail::with(['order','order.user','order.place','product','period'])->get()->groupBy(['period_id','place_id'])->toArray();

1 Ответ

0 голосов
/ 28 февраля 2019

Я решил это.

OrderDetail::with(['order','order.user','order.place','product','period'])->get()->groupBy(['period.id','order.place.id'])->map(function ($periods) {
            $period = $periods->first()->first()->period;
            return [
                "start_time" => $period->start_time,
                "end_time" => $period->end_time,
                "places" => $periods->map(function ($places) {
                    $place = $places->first()->place;
                    return [
                        "name" => $place->name,
                        "address" => $place->address,
                        "details" => $places->toArray()
                    ];
                })->toArray()
            ];
        })->toArray();
...