Laravel渴望加载计数关系

时间:2017-05-09 12:52:09

标签: php laravel eager-loading

我有三个型号,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位了,我无法通过订单表创建联接以按订单状态进行过滤。

1 个答案:

答案 0 :(得分:2)

你可以做如下的事情,这种关系可能需要一些修补:

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();