使用 Eloquent 从两个数据透视表中预加载总和
Eager loading sum from two pivot tables with Eloquent
我有一个 Part 实体,它与 Order 和 Project[= 存在多对多关系23=]。数据透视表包含一个 quantity
字段,该字段可能具有正值或负值,通过将两个数据透视表的总和相加,对于特定部分,我得到当前库存。
我能做到这一点,但遇到了 N+1 问题。而且我很难弄清楚如何通过预加载来做到这一点。我读过这个 post,但我不明白如何根据我的需要调整它。
所以我正在寻找一种在 Part 模型上提供急切可加载库存 属性 的方法,关于如何实现这一点的建议?
我能够在这个 post 的帮助下解决这个问题。这就是我所做的:
零件型号
创建两个关系 orderPartsCount
和 projectPartsCount
,添加属性 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);
}
部分控制器
在控制器中预先加载 orderPartsCount
和 projectPartsCount
。
public function index()
{
return View::make('parts.index', [
'parts' => Part::with('category', 'location', 'orderPartsCount', 'projectPartsCount')
->orderBy('description_no')
->paginate(100)
]);
}
我有一个 Part 实体,它与 Order 和 Project[= 存在多对多关系23=]。数据透视表包含一个 quantity
字段,该字段可能具有正值或负值,通过将两个数据透视表的总和相加,对于特定部分,我得到当前库存。
我能做到这一点,但遇到了 N+1 问题。而且我很难弄清楚如何通过预加载来做到这一点。我读过这个 post,但我不明白如何根据我的需要调整它。
所以我正在寻找一种在 Part 模型上提供急切可加载库存 属性 的方法,关于如何实现这一点的建议?
我能够在这个 post 的帮助下解决这个问题。这就是我所做的:
零件型号
创建两个关系 orderPartsCount
和 projectPartsCount
,添加属性 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);
}
部分控制器
在控制器中预先加载 orderPartsCount
和 projectPartsCount
。
public function index()
{
return View::make('parts.index', [
'parts' => Part::with('category', 'location', 'orderPartsCount', 'projectPartsCount')
->orderBy('description_no')
->paginate(100)
]);
}