Acompanhe facilmente a contagem de relacionamento de rails com counter_cache

Os logs do seu servidor Rails estão cheios de linhas como esta:

(0.3ms) SELECT COUNT(*) FROM "comments" WHERE "comments"."post_id" = 1

Ou talvez você apenas queira armazenar o número de filhos que um modelo pai mantém para fazer algumas consultas de cálculo

Configuração

Configurar counter_cache é bastante simples. Consiste apenas em adicionar um novo campo que armazene um valor de contador que será atualizado sempre que um membro for adicionado / removido da coleção através dos callbacks de ActiveRecord .

# app/models/post.rb
class Post < ActiveRecord::Base
has_many
:comments
end

# app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to
:post, counter_cache: true
end

Em seguida, criamos a migração:

class AddCommentsCountToPosts < ActiveRecord::Migration
def change
add_column
:posts, :comments_count, :integer, default: 0, null: false

# Update the counter for existing records
Post.select(:id) do |result|
Post.reset_counters(result.id, :comments)
end
end
end

E isso é tudo que precisamos fazer! 🙂

Agora podemos facilmente fazer algumas consultas como:

Post.where("created_at > ?", 2.month.ago).average(:comments_count)

Nota 1: Também funciona com associações polimórficas (apesar de parecer precisar de uma configuração adicional

Nota 2: o contador só é atualizado na criação e exclusão do modelo . Se você precisar mudar algo quando for atualizado, você precisará de uma solução alternativa como esta ou você pode usar esta joia

Créditos: ElegantRuby , StackOverflow e guia Rails