I have two models I link together using a polymorphic has_many through association and I would like to add a counter_cache but it seems Rails/ActiveRecord does not support this feature out of the box.
class Classifiable < ActiveRecord::Base
has_many :classifications, :as => :classifiable, :foreign_key => :classifiable_id
end
class Taxonomy < ActiveRecord::Base
has_many :classifications, :as => :taxonomy, :foreign_key => :taxonomy_id
end
class Question < Classifiable
has_many :categories, :through => :classifications, :as => :classifiable, :source => :taxonomy, :source_type => "Category"
end
class Category < Taxonomy
has_many :questions, :through => :classifications, :source => :classifiable, :source_type => "Question"
end
class Classification < ActiveRecord::Base
attr_accessible :classifiable, :classifiable_id, :classifiable_type,
:taxonomy, :taxonomy_id, :taxonomy_type
belongs_to :classifiable, :polymorphic => true
belongs_to :taxonomy, :polymorphic => true
end
Simply modify your Classification model for the following:
Also, make sure you have the following columns in your taxonomies table:
Change "other_classifiables_count" to what you need ("answers_count", "users_count", etc.)
To modify Jonathan's answer a bit, you could make it look up the column type to see if it exists before incrementing/decrementing. I also DRYed it up a bit:
Oh and it works with
MultiWordClassNames
.underscore
does adowncase
so my version omits it.It seems like Rails does not go through the before/after_destroy callbacks when calling delete (what happens when you remove a has many through association).
Instead, you can use the association's callbacks
#before_add
and#before_remove
: