Counter caches are really useful to keep a track of the amount of related data a given record has. Unfortunately, it's a delicate setup for
I started to implement experimentslabs.com using Ruby on Rails for learning reasons, and I had a hard time implementing counter caches on
First, I tried with callbacks, but the
after_destroy callback was not fired, so the counters were only growing up.
Then, I changed the relations to
has_many through: :xxx, with the idea of putting the
counter_cache declaration in the pivot table. Again, to callback fired on destoy (even with
dependent: true). I hope this is not linked to this open issue from 2014 titling "Fails to invoke
after_remove callback when deleting associated record"
During my research, I found this great post by jjmars, and I finally came to this solution:
# album.rb class Album < ApplicationRecord has_many :albums_tags has_many :tags, through: :albums_tags, dependent: :destroy end # tag.rb, contains field "albums_count" class Tag < ApplicationRecord has_many :albums_tags has_many :albums, through: :albums_tags end # albums_tag.rb class AlbumsTag < ApplicationContentRecord belongs_to :album belongs_to :tag after_create :increment_counter_cache after_destroy :decrement_counter_cache private def increment_counter_cache tag.update(albums_count: (tag.albums_count + 1)) end def decrement_counter_cache tag.update(albums_count: (tag.albums_count - 1)) end end
Hope this helps :)
Leave a comment
You want to react to this content or ask something to the author? Just leave a comment here!
Note that the comments are not publicly visible, so don't worry if you don't see yours.
All the information you give will only be visible to the author. We don't share anything with anyone.