I have User
model which has_many :notifications
. Notification
has a boolean column seen
and a scope called :unseen
which returns all notifications where seen
is false
.
class User < ApplicationRecord
has_many :notifications
has_many :unseen_notifications, -> { unseen }, class_name: "Notification"
end
I know that I can cache the number of notifications if I add a column called notifications_count
to users
and add counter_cache: true
to my belongs_to
call in Notification
.
But what if I want to cache the number of unseen notifications a user has? I.e. cache unseen_notifications.size
instead of notifications.size
? Is there a built-in way to do this with counter_cache
or do I have to roll my own solution?
According to this blog post, there is no built-in way to use counter caches for scoped associations:
ActiveRecord’s counter cache callbacks only fire when creating or destroying records, so adding a counter cache on a scoped association won’t work. For advanced cases, like only counting the number of published responses, check out the counter_culture gem.
Other than using an external gem, you could roll your own solution by adding callbacks to your Notification
model and adding an integer column (e.g., unseen_notifications_count
) to the User
model:
# 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
Also see the answers to Counter Cache for a column with conditions? for additional implementation examples of this approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With