Saving object after adding an has_many element with counter cache reset the database value of the counter cache to the value loaded from database.
For example post.comments_count gives 1 but post.attributescomments_count? gives 0.
instanciated object is right but value in object attribues are wrong (the only method i found for now is to do post.reload and continue)
In case this code does not follow good practices, any correction is welcome :)
example in console :
>> Post.find_all
=> []
>> post = Post.create
=> #<Post:0xb75d0120 @new_record=false, @errors=#<ActiveRecord::Errors:0xb75cee60 @errors={}, @base=#<Post:0xb75d0120 ...>>, @new_record_before_save=true, @attributes={"title"=>nil, "id"=>1, "comments_count"=>0}>
>> post.comments.create()
=> #<Comment:0xb75c6ef4 @new_record=false, @commentable=#<Post:0xb75c30ec @attributes={"title"=>nil, "id"=>"1", "comments_count"=>"0"}>, @errors=#<ActiveRecord::Errors:0xb75c5d88 @errors={}, @base=#<Comment:0xb75c6ef4 ...>>, @attributes={"commentable_type"=>"Post", "updated_at"=>Thu May 11 17:05:10 CEST 2006, "id"=>3, "commentable_id"=>1, "created_at"=>Thu May 11 17:05:10 CEST 2006}>
>> post.comments_count
=> 1
>> post.title = 'test'
=> "test"
>> post.save
=> true
>> post.comments_count
=> 1
>> post.id
=> 1
>> post = Post.find(1)
=> #<Post:0xb75ad2c4 @attributes={"title"=>"test", "id"=>"1", "comments_count"=>"0"}>
>> post.comments_count
=> 0
Models :
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true, :counter_cache => true
end
class Post < ActiveRecord::Base
has_many :comments, :as => :commentable, :dependent => :destroy
end
class Photo < ActiveRecord::Base
has_many :comments, :as => :commentable, :dependent => :destroy
end
Migrations :
class CreatePhotos < ActiveRecord::Migration
def self.up
create_table :photos do |t|
t.column :title, :string
t.column "comments_count", :integer, :default => 0, :null => false
end
end
def self.down
drop_table :photos
end
end
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.column :title, :string
t.column "comments_count", :integer, :default => 0, :null => false
end
end
def self.down
drop_table :posts
end
end
class CreateComments < ActiveRecord::Migration
def self.up
create_table "comments" do |t|
t.column "commentable_type", :string
t.column "commentable_id", :integer
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
end
def self.down
drop_table :comments
end
end