Laravel Eloquent - объединение двух красноречивых результатов модели (не коллекций) - PullRequest
1 голос
/ 17 апреля 2019

У меня есть таблица движения запаса, которая показывает историю продукта (получение, перемещение и т. Д.)

У меня есть два запроса, которые рассчитывают (через совокупные суммы):

  1. Оригинал получил кол-во.
  2. Текущее количество в реальном времени (после того, как что-то было перемещено).

Оба эти запроса возвращают коллекцию одинаковых моделей. У них всегда будет одинаковое количество результатов в каждом, а product_id всегда будет одинаковым. Единственная отличающаяся часть - это количество полученных / живых, и я хочу как-то объединить отдельные записи в новую коллекцию. т.е.

Отдельная запись из запроса 1:

0 => StockMovement {#1602 ▼
  #original: array:2 [▼
    "live_qty" => "8"
    "product_id" => "2606598e-4150-461a-9e91-10d67cce8daa"
  ]
}

Отдельная запись из запроса 2;

0 => StockMovement {#1602 ▼
  #original: array:2 [▼
    "received_qty" => "15"
    "product_id" => "2606598e-4150-461a-9e91-10d67cce8daa"
  ]
}

Я пытаюсь получить объединенный результат, который выглядит следующим образом:

0 => StockMovement {#1602 ▼
  #original: array:3 [▼
    "received_qty" => "15"
    "live_qty" => "8"
    "product_id" => "2606598e-4150-461a-9e91-10d67cce8daa"
  ]
}

Я хочу сделать это способом, который не преобразует объект Product в массив, поскольку мне нужны встроенные в него отношения.

В настоящее время я взломал это следующим образом:

$live = $this->liveQtyCollection();
$merged = $this->receivedQtyCollection()->map(function(StockMovement $received) use($live){
    $line = $live->where('product_id', $received->product_id)->first();
    return arrayToObject(array_merge($received->toArray(), $line->toArray()));
});
return $merged;

Функция arrayToObject рекурсивно преобразует массив обратно в объект, чтобы я мог использовать селектор стрелок так же, как и в случае его оригинальной коллекции, но я уверен, что должен быть лучший способ!

Я пробовал:

  • Слияние
  • Union
  • Все

Моя конечная цель - использовать полученную коллекцию следующим образом:

@foreach($stockMovements as $stockMovement)
    {{ $stockMovement->id }}
    {{ $stockMovement->live_qty }}
    {{ $stockMovement->received_qty }}
@endforeach

Ответы [ 2 ]

0 голосов
/ 18 апреля 2019

Вы можете сделать что-то вроде этого:

$live = $this->liveQtyCollection()->keyBy('product_id')
$merged = $this->receivedQtyCollection()->map(function(StockMovement $received) use($live){
    $received->live_qty = $live->get($received->product_id)->live_qty ?? null;
    return $received;
});
0 голосов
/ 17 апреля 2019

Вы можете использовать этот код:

$collection = collect();
$cars = Car::all();
$bikes = Bike::all();

foreach ($cars as $car)
    $collection->push($car);

foreach ($bikes as $bike)
    $collection->push($bike);

Источник

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...