【问题标题】:Laravel eager loading count relationLaravel 急切加载计数关系
【发布时间】:2017-05-09 23:11:04
【问题描述】:

我有三个模型,Order、OrderProduct 和 Product。 OrderProduct 是从 Order 和 Product 创建关系的表,用于存储价格或数量等信息。在我的产品列表操作中,我需要显示每种产品有多少订单处于打开状态(待处理或已支付)。所以我试图像这样急切地加载这种关系:

// ProductController.php

public function index()
{
    $data = Product::with(['reservedStock']);

    return $data;
}

//Product.php

public function reservedStock()
{
    return $this->hasMany(OrderProduct::class, 'product_sku')
        ->selectRaw('order_products.product_sku, count(*) as count')
        ->join('orders', 'orders.id', 'order_products.order_id')
        ->whereIn('orders.status', [Order::STATUS_PENDING, Order::STATUS_PAID]);
}

它可以工作,但它的响应是这样的数组:

{
    "sku": 384,
    "brand_id": null,
    "line_id": null,
    "title": "Alcatel Pixi 4 Colors OT4034E 8GB 3G Preto",
    "ean": null,
    "ncm": 85171231,
    "price": "315.44",
    "cost": "0.00",
    "condition": 0,
    "warranty": null,
    "created_at": "2016-08-25 10:45:40",
    "updated_at": "2017-03-30 17:51:07",
    "deleted_at": null,
    "reserved_stock": [
        {
            "product_sku": 384,
            "count": 4
        }
    ]
}

我只想要计数reserved_stock: 4

关于如何做的任何想法?

ps:我已经尝试过使用它进行withCount 位,我无法从订单表创建连接以按订单状态进行过滤。

【问题讨论】:

  • 阅读本文可能会对您有所帮助:stackoverflow.com/questions/20770284/…
  • @Daan 这不是急于加载。我只想查询我的所有产品。根据您的参考,他创建了另一个属性,即计数,然后我在 foreach 或其他东西上调用它。我需要在显示之前加载它。
  • 您只能返回计数。 return count($product->reservedStock);?
  • 这样的计数不足以满足您的目的,它应该 sum(order_products.quantity) 或其他东西,您可以使用查询构建器 sum() 方法重新计算该总和
  • @DimitrisKontoulis 我知道,这只是一个示例目的。

标签: php laravel eager-loading


【解决方案1】:

您可以执行以下操作,关系可能需要一些修补:

public function reservedStockCount()
{
    return $this->belongsToMany(OrderProduct::class)
        ->selectRaw('order_products.id, count(*) as aggregate_reserved_stock')
        ->join('orders', 'orders.id', 'order_products.order_id')
        ->whereIn('orders.status', [Order::STATUS_PENDING, Order::STATUS_PAID]);
        ->groupBy('order_products.id');
}

public function getReservedStockCount()
{
    // if relation is not loaded already, let's do it first
    if (!array_key_exists('reservedStockCount', $this->relations)) {
        $this->load('reservedStockCount');
    }

    $related = $this->getRelation('reservedStockCount')->first();
    // then return the count directly
    return ($related) ? (int) $related->aggregate_reserved_stock : 0;
}

并且可以如下使用:

Product::with(['reservedStockCount']);

Product->getReservedStockCount();

【讨论】:

  • 成功了!当我使用 laravel 作为 API 时,我需要创建一个自定义属性并使用您的方法将其附加到我的模型中。谢谢!
  • 很高兴能帮上忙!
猜你喜欢
  • 2014-06-21
  • 2021-12-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 2020-12-15
相关资源
最近更新 更多