Counter cache com acts_as_tree
Estava fazendo uns testes esses dias com uma aplicação Rails que utiliza acts_as_tree. Estava utilizando o size() para saber se o objeto tinha filhos, foi então que me veio a idéia de implementar o counter_cache e assim dar uma boa limpada nas consultas executadas.
Pesquisei na documentação como fazer isso e bastava colocar o campo com o nome de children_count, porém quando adicionei o :counter_cache => true no act_as_tree o autotest já me acusou 2 erros de SQL. Com uma pesquisada no Google consegui encontrar a solução, basta usar o nome do campo como parâmetro para o :counter_cache.
Criando a migration
script/generate migration add_pages_count
Então editei ela para ficar com o código abaixo, atente para o nome children_count do campo.
class AddPagesCount < ActiveRecord::Migration
def self.up
add_column :pages, :children_count, :integer, :default => 0
Page.reset_column_information
Page.all.each do |p|
Page.update_counters p.id, :children_count => p.children.count
end
end
def self.down
remove_column :pages, :children_count
end
end
execute a migration tanto no seu banco de desenvolvimento como no test.
rake db:migrate && rake db:migrate RAILS_ENV=test
Adicionando o counter_cache
a solução está exatamente aqui, descobri que basta você passar o nome do campo que deseja usar para o counter_cache, ficou assim:
class Page < ActiveRecord::Base acts_as_tree :counter_cache => "children_count" end
Tests
agora uma alteração que eu tive que fazer nos meus teste foi adicionar o filho com o metodo create e não como o new
require File.dirname(__FILE__) + '/../test_helper'
class PageTest < Test::Unit::TestCase
context "A page instance" do
should "be able to have children" do
assert_difference "Page.count", 1 do
assert_difference "pages(:home).children.size", 1 do
pages(:home).children.create(:title=>"Sign Up", :body=>"Sign up text!")
end
end
end
end
end
Bom é só isso simples assim, espero que possa ajudar alguém.