我有两种模式:类别和广告。 类别has_many:广告 +我添加了计数器缓存:ads_count 。我使用 gem awesome_nested_set 来制作嵌套类别,因此Category1可以是Category2的父/子,可以是Category3的父类等。我需要的类别#index是计算所属广告的总和特定类别或儿童类别(或“孙子”等)。我现在的解决方案是: some_nested_categories.sum(:ads_count)。但是,假设我的索引页面中有很多类别,它会使许多查询检索所有数据并且需要很长时间。我怎样才能更有效地做到这一点?谢谢你的帮助!
答案 0 :(得分:0)
您可以手动为counter_cache
扩展sum_cache
的想法,让我们称之为nested_ads_count
。
然后会有4个需要处理的一般情况
after_update
回调,当当前的nested_ads_count
或nested_ads_count
更新时,会更新家长的ads_count
。解决了第一个案例。
awesome_nested_set解决了其他2个案例
使用after_add
和after_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阻止这种情况。