Counter cache is a mechanism to cache the counts of associated model. The counter cache works by simply updating a parent model's count of related objects after each save or destroy operation on the child model. It increase the counts when associated object is created and decrease the counts when associated object is destroyed.
Why counter cache?
Many times we need the count's of child objects and we use through association to display counts on view in this case multiple SQL queries are raised just to get counts.
One of the traditional example is to display comment counts with every user.
class User < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
end
Now get user records with every user comment counts.
To display this counts what rails did.
To solve this issue we can go for active record counter cache.
How to implement counter cache?
We can implement counter cache in three steps
1) Create migration to add column in user table.
class AddCounterCacheToUsers < ActiveRecord::Migration
def self.up
add_column :users, :comments_count, :integer, :default => 0
end
def self.down
remove_column :users, :comments_count
end
end
2) Update existing record of user for comment counts
class AddCounterCacheToUsers < ActiveRecord::Migration
def self.up
add_column :users, :comments_count, :integer, :default => 0
User.find_each do |user|
user.update_attribute(:comments_count, user.comments.length)
user.save
end
end
def self.down
remove_column :users, :comments_count
end
end
After run the migration.
3) Apply counter cache on comment model.
class Comment < ActiveRecord::Base
belongs_to :user , :counter_cache => true
end
and replace the code of user index view
<%=h user.comments.length %>
with
<%=h user.comments_count %>
Now we can get user comments count from same table with no extra query.