简体   繁体   English

Laravel Eloquent - 合并两个 eloquent 模型结果(不是集合)

[英]Laravel Eloquent - Merging two eloquent model results (not the collections)

I have a table of stock movements, which shows a history of a product (receiving, moving location etc.)我有一张库存变动表,其中显示了产品的历史记录(接收、移动位置等)

I have two queries which calculate (via aggregate sums):我有两个计算(通过总和)的查询:

  1. The original received qty.原收到数量。
  2. The current live qty (after things have been moved).当前的实时数量(在事物被移动之后)。

Both of these queries return a collection of the same models.这两个查询都返回相同模型的集合。 They will always have the same number of results in each, and the product_id's will always be the same.它们将始终具有相同数量的结果,并且 product_id 将始终相同。 The only part that is different is the received/live qty and I want to somehow merge the individual records into a new collection.唯一不同的部分是接收/实时数量,我想以某种方式将各个记录合并到一个新集合中。 ie IE

Single record from query 1:查询 1 中的单个记录:

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

Single record from query 2;查询 2 中的单个记录;

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

I am trying to end up with a merged result which looks like the following:我试图最终得到一个如下所示的合并结果:

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

I want to do this in a way that does not convert the Product object to an array, as I need the relationships that are embedded within it.我想以不将 Product 对象转换为数组的方式执行此操作,因为我需要嵌入其中的关系。

Currently, I have hacked this as follows:目前,我已将其破解如下:

$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;

The arrayToObject function, recursively converts the array back into an object so I can use the arrow selector in the same way as when it was its original collection, but I am sure there must be a better way! arrayToObject函数递归地将数组转换回对象,这样我就可以像使用它的原始集合时一样使用箭头选择器,但我相信一定有更好的方法!

I have tried:我试过了:

  • Merge合并
  • Union联盟
  • All全部

My end goal is to be able to use the resulting collection as follows:我的最终目标是能够按如下方式使用生成的集合:

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

You can use this code:您可以使用此代码:

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

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

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

Source 来源

You could do something like this:你可以这样做:

$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;
});

I know you mentioned in your question that you did not mean collections and also that you had already tried merging, but for the sake of discussion I thought I'd throw my answer in the mix, as this worked precisely for what I needed;我知道你在你的问题中提到你并不是说集合,而且你已经尝试过合并,但为了讨论起见,我想我会把我的答案混在一起,因为这正是我需要的; merging the responses of two model calls.合并两个模型调用的响应。

$quote = \App\AllQuotes::withoutGlobalScopes()->find($quote_id);
$settings = \App\Settings::findOrFail(1);
$settings = collect($settings);
$quote = collect($quote);
$merged = $quote->merge($settings);

return $merged;

You have to first encapsulate the model responses as collections with the collect helper, then you can merge them together.您必须首先使用collect助手将模型响应封装为集合,然后才能将它们合并在一起。 The output then treats it as a logical join, maintaining the data from both models in a singular output.然后输出将其视为逻辑连接,将来自两个模型的数据保存在单一输出中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM