Rails上的counter_cache有关作用域的关联

时间:2016-05-04 13:52:41

标签: ruby-on-rails activerecord associations named-scope counter-cache

我有User模型has_many :notificationsNotification有一个布尔列seen和一个名为:unseen的范围,它返回seenfalse的所有通知。

class User < ApplicationRecord
  has_many :notifications
  has_many :unseen_notifications, -> { unseen }, class_name: "Notification"
end

如果我向notifications_count添加名为users的列并将counter_cache: true添加到belongs_to,我知道我可以缓存通知的数量}呼叫Notification

但是如果我想缓存用户拥有的看不见的通知的数量呢?即缓存unseen_notifications.size而不是notifications.size?是否有内置方法可以使用counter_cache执行此操作,还是必须自行解决此问题?

1 个答案:

答案 0 :(得分:0)

根据this blog post,没有内置方法可将计数器缓存用于范围内的关联:

  

ActiveRecord的计数器缓存回调仅在创建或销毁记录时触发,因此无法在作用域关联上添加计数器缓存。对于高级情况,例如仅计算已发布的响应数,请查看counter_culture gem。

除了使用外部gem之外,您还可以通过向Notification模型添加回调并向unseen_notifications_count模型添加整数列(例如User)来推出自己的解决方案:

# Notification.rb
after_save    :update_counter_cache
after_destroy :update_counter_cache

def update_counter_cache
  self.user.unseen_notifications_count = self.user.unseen_notifications.size
  self.user.save
end

有关此方法的其他实现示例,另请参见Counter Cache for a column with conditions?的答案。