#78 Counter Cache Associations


When displaying a count of records, this will generate extra SQL Queries. Learn how to reduce the number of SQL queries called with counter caching the number of associated records.
rails model cache 3:54


companies/index.html.erb# Bad
<%= company.users.length %>

# Good
<%= company.users_count %>
<%= company.users.size %>
user.rbclass User < ApplicationRecord
  belongs_to :company, counter_cache: true 
  # DEFAULT Column: users_count
  # belongs_to :company, counter_cache: :users_size 

Terminalrails g migration add_counter_cache_to_companies users_count:integer
db/migrate/20170501010016_add_counter_cache_to_companies.rbclass AddCounterCacheToCompanies < ActiveRecord::Migration[5.0]
  def change
    add_column :companies, :users_count, :integer, default: 0
    Company.find_each { |company| Company.reset_counters(company.id, :users) }

scytherswings said over 2 years ago on Counter Cache Associations :

I feel like the video skipped over the


method and its behavior. Could you add that to the samples below?

kobaltz PRO said over 2 years ago on Counter Cache Associations :

count will perform similar to size. However, for the life of the object (typically just the instance of the request), it will perform another Count(*) query. So, if you are getting the count of an object multiple times within a view or method of that instance, it would make multiple database calls.

length can actually be fast if you have already eager loaded the objects from the association. However, for the most part, I avoid length.

size is similar to count with the exception that it will "cache" the Count(*) query or perform it if necessary. It's basically like a memoization of the count.

scytherswings said over 2 years ago on Counter Cache Associations :

I didn't realize that `.count` was so inefficient, looks like I have some optimization to do. Thanks for the information!

Login to Comment