从Eloquent的两个数据透视表中急切加载总和

时间:2015-08-19 17:01:11

标签: laravel-5 eloquent pivot-table eager-loading

我有一个与订单项目有多对多关系的 Part 实体。数据透视表包含quantity字段,可能具有正值或负值,通过添加两个数据透视表的总和,对于特定部分,我获得当前存货。

我能够做到这一点,但得到了N + 1问题。而且我很难搞清楚如何通过急切加载来实现这一目标。我已经阅读了这个post,但我不明白如何使其适应我的需求。

所以我正在寻找一种在 Part 模型上提供热切的可加载股票属性的方法,以及如何实现这一目标的建议?

1 个答案:

答案 0 :(得分:0)

我能够借助post来解决这个问题。这就是我所做的:

零件模型

创建两个关系orderPartsCountprojectPartsCount,添加属性calculatedStock以对它们求和,并提供一种简单的检索方式。

public function orderPartsCount()
{
    $a = $this->orders();
    $a1 = $a->selectRaw($a->getForeignKey() . ', sum(count) as stock')
            ->where('done', '>', 0)
            ->groupBy($a->getForeignKey()
        );

    return $a1;
}

public function projectPartsCount()
{
    $b = $this->projects();
    $b1 = $b->selectRaw($b->getForeignKey() . ', sum(count) as stock')
            ->where('status', '>', 0)
            ->groupBy($b->getForeignKey()
        );

    return $b1;
}

public function getCalculatedStockAttribute()
{
    $orders = $this->orderPartsCount->first() ? $this->orderPartsCount->first()->stock : 0;
    $projects = $this->projectPartsCount->first() ? $this->projectPartsCount->first()->stock : 0;

    // invert project parts, since they are listed as positive counts but shall reduce the stock
    return $orders + ( $projects * -1);
}

部分控制器

在控制器中预先加载orderPartsCountprojectPartsCount

public function index()
{
    return View::make('parts.index', [
        'parts' => Part::with('category', 'location', 'orderPartsCount', 'projectPartsCount')
            ->orderBy('description_no')
            ->paginate(100)
    ]);
}