As far as I can tell, the counter_cache option on a belongs_to model
doesn’t actually save anything in the database. For example, I have
the following models:
class Parent < ActiveRecord::Base
has_many :children,
:conditions => “deleted_at IS NULL”
end
class Child < ActiveRecord::Base
belongs_to :parent, :counter_cache => true
end
With the following schema, dumped from sqlite3:
CREATE TABLE children (“id” INTEGER PRIMARY KEY NOT NULL NOT NULL,
“name” varchar(255), “parent_id” integer, “deleted_at” datetime);
CREATE TABLE parents (“id” INTEGER PRIMARY KEY NOT NULL NOT NULL,
“children_count” integer DEFAULT 0, “name” varchar(255));
CREATE TABLE schema_info (version integer);
CREATE UNIQUE INDEX children_id_index ON children (id);
CREATE UNIQUE INDEX parents_id_index ON parents (id);
I would expect the children_count column in each Parent to be
populated with the number of children as I create and delete
associated children. However, that does not seem to be the case.
For example, I create a new parent and child in the console and verify
the number of children. When I quit and restart the console, however,
the children_size column is 0.
[flashbang:…WebContent/rails/development/test] ryann% ./script/console
Loading development environment.
parent = Parent.create
=> #<Parent:0x2385f24 @new_record_before_save=false,
@new_record=false, @errors=#<ActiveRecord::Errors:0x2351dc8
@errors={}, @base=#<Parent:0x2385f24 …>>, @attributes={“name”=>nil,
“id”=>1, “children_count”=>0}>parent.children.create
=> #<Child:0x234d070 @new_record=false,
@errors=#<ActiveRecord::Errors:0x2349e48 @errors={},
@base=#<Child:0x234d070 …>>, @attributes={“name”=>nil,
“deleted_at”=>nil, “id”=>1, “parent_id”=>1},
@parent=#<Parent:0x23461d0 @attributes={“name”=>nil, “id”=>“1”,
“children_count”=>“0”}>>parent.children.size
=> 1parent.children_count
=> 1Parent.find_first
=> #<Parent:0x233fee8 @attributes={“name”=>nil, “id”=>“1”,
“children_count”=>“1”}>parent.save
=> truequit
[flashbang:…WebContent/rails/development/test] ryann% ./script/console
Loading development environment.Parent.find_first
=> #<Parent:0x2353d30 @attributes={“name”=>nil, “id”=>“1”,
“children_count”=>“0”}>
That is not at all what I expected to happen. Rather, since I
specified the counter_cache option in the Child model, I expected to
see children_count be equal to 1 after restarting the console.
Why have a database column if nothing is to be stored there? The
counter_cache option seems exceedingly useless, otherwise. At the very
least, it doesn’t make any sense to create the column if nothing is to
be written there… Did I screw up something?
–
Ryan