【问题标题】:Laravel Eloquent - Merging two eloquent model results (not the collections)Laravel Eloquent - 合并两个 eloquent 模型结果(不是集合)
【发布时间】:2019-09-08 03:18:03
【问题描述】:

我有一张库存变动表,其中显示了产品的历史记录(接收、移动位置等)

我有两个计算查询(通过总和):

  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 函数递归地将数组转换回对象,这样我就可以像原来的集合一样使用箭头选择器,但我相信一定有更好的方法!

我试过了:

  • 合并
  • 联合
  • 全部

我的最终目标是能够按如下方式使用生成的集合:

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

【问题讨论】:

  • “Eloquent 返回的所有多结果集都是 Illuminate\Database\Eloquent\Collection 对象的实例”。为什么说不是收藏?
  • 我想我认为集合是“雄辩的模型结果的集合”。我想确保不会将 stockMovement 模型分解为数组或普通集合,即我想通过 product_id 保留其所有关系功能,例如 $stockMovement->product->title 其中 stockMovement 属于产品
  • 我想你可以试试这种方式:laravel.com/docs/5.8/eloquent-relationships
  • @loic.lopez 谢谢。我已经知道什么是关系。我只是想合并上述两个查询,同时保持关系完整。如果我在合并之前转换为数组,那么关系就会丢失。

标签: php laravel eloquent query-builder laravel-query-builder


【解决方案1】:

我知道你在你的问题中提到你并不是说集合,而且你已经尝试过合并,但为了讨论,我想我会把我的答案混在一起,因为这正好适合我需要;合并两个模型调用的响应。

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

return $merged;

您必须首先使用 collect 帮助器将模型响应封装为集合,然后您可以将它们合并在一起。然后输出将其视为逻辑连接,将来自两个模型的数据保存在单个输出中。

【讨论】:

    【解决方案2】:

    你可以这样做:

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

    【讨论】:

      【解决方案3】:

      您可以使用此代码:

      $collection = collect();
      $cars = Car::all();
      $bikes = Bike::all();
      
      foreach ($cars as $car)
          $collection->push($car);
      
      foreach ($bikes as $bike)
          $collection->push($bike);
      

      Source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        • 2019-10-13
        • 2014-05-29
        • 2018-11-11
        • 2017-09-13
        相关资源
        最近更新 更多