0

我有两个模型:CategoryAd类别 has_many :ads + 我添加了计数器缓存 :ads_count。我使用gem awesome_nested_set来制作嵌套类别,因此 Category1 可以是 Category2 的父/子,可以是 Category3 的父等。我的类别#index 需要计算属于某个类别或子类别的广告总和(或“孙子”等)。我现在的解决方案是:some_nested_categories.sum(:ads_count)。但是假设我的索引页面中有很多很多类别,它会进行很多查询来检索所有这些数据,并且花费的时间太长。我怎样才能更有效地做到这一点?感谢帮助!

4

1 回答 1

0

您可以将counter_cache手动的想法扩展为一种sum_cache,让我们称之为nested_ads_count

那么将有4个一般情况需要处理

  • 一个类别得到一个新的添加
  • 一个类别被“移动/添加”到一个新的父类别”
  • 一个类别被删除(或从父级中删除)”

当当前或更新时after_update更新父级的回调。解决了第一种情况。 nested_ads_countnested_ads_countads_count

awesome_nested_set 解决了其他两种情况

使用after_addafter_remove回调重新计算nested_ads_count.

计算和缓存的方法nested_ads_count如下所示

def reset_nested_ads_count
  self.nested_ads_count = some_nested_categories.sum(:nested_ads_count) + self.ads_count
end

当使用计数的频率大于更新频率时,此方法是最佳的,因为它仅在更新数字时进行耗时查询,而不是在需要查看数字时进行查询。

有一个可能发生的陷阱,那就是如果你的嵌套中有一个循环(a > b > a,或者更阴险的 a > b > c > ... > a),你可能会让自己陷入无限循环. 我没有看到任何明确说明 awesome_nested_set 阻止了这种情况。

于 2017-07-28T15:01:32.530 回答