嵌套模型的计数总和

时间:2017-07-28 13:38:40

标签: ruby-on-rails nested counter-cache awesome-nested-set

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

1 个答案:

答案 0 :(得分:0)

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

然后会有4个需要处理的一般情况

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

after_update回调,当当前的nested_ads_countnested_ads_count更新时,会更新家长的ads_count。解决了第一个案例。

awesome_nested_set解决了其他2个案例

使用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阻止这种情况。