我有两个简单的1-n关系模型(类别和具有category_id的项目)。我想说明该类别中有多少项目。我想将数字缓存而不是总是进行计数,所以我在类别表中有一个名为“total_items_count”的额外字段。 如何最好地执行此总计数触发,何时调用“countUpdate”函数,因为关系可能会从多个位置(后端,api,前端......)发生变化。
我最初的计划是使用AFTER_UPDATE事件,但是在项目存储在数据库中之后必须调用“link()”(至少在添加新项目时),因此我不知道哪个类别是与之相关的项目。我还需要知道旧类别,以防项目从一个类别转到另一个类别。在后端控制器中,我使用$ item-> link('category',$ categoryObj);因为有一天我可能会改变这种与n-n的关系。
如果项目和类别之间的链接发生变化,然后更新旧链接类别和新链接类别的计数,有关如何完全控制的建议吗? 感谢
答案 0 :(得分:0)
您现在需要做的第一件也是最重要的事情是,您需要通过ActiveRecord::updateCounters()
方法更新类别计数字段,以防止从多个位置进行不正确的更新。所以你可以做其中的一件事:
在类别项目模型中,您可以执行以下操作:
public function save($runValidation = true, $attributeNames = null)
{
if (parent::save(runValidation, attributeNames)) {
$this->category->updateCounters(['total_items_count' => 1]);
return true;
}
return false;
}
或者您可以编写一个集中组件(让我们说app \ components \ Category),您将从整个应用程序中调用它。该组件将具有保存项目的方法。例如:
public function saveItem($category, $item)
{
if ($item->save()) {
$item->link('category', $category);
$category->updateCounters(['total_items_count' => 1]);
return true;
}
return false;
}
当然,当您删除某个项目时,您将调用:
$category->updateCounters(['total_items_count' => -1]);
See the ActiveRecord::updateCounters() API
来自Yii2文档:
注意:如果你使用yii \ db \ ActiveRecord :: save()来更新计数器列,你可能会得到不准确的结果,因为很可能同一个计数器被读取和写入的多个请求保存。相同的价值。
如果你需要跟踪哪个是旧类别,只需创建另一个列,让我们说" old_category"到类别项目表,当您更改项目的类别时,将旧类别ID放在那里,将新类别ID放入category_id列。
这有帮助吗?如果您有任何疑问,请询问!