1

I have a many-to-many association between a Post and a Tag model:

post.rb:

 has_many :taggings, dependent: :destroy  
 has_many :tags, through: :taggings

tag.rb:

has_many :taggings, :dependent => :destroy  
has_many :posts, :through => :taggings

tagging:

attr_accessible :tag_id, :post_id

belongs_to :post
belongs_to :tag

I want to have a page where I list all the tags and how many posts each tag has.

So I added a posts_count column to tags:

  create_table "tags", :force => true do |t|
    t.string   "name"
    t.datetime "created_at",                 :null => false
    t.datetime "updated_at",                 :null => false
    t.integer  "posts_count", :default => 0, :null => false
  end

I've used counter cache before:

reply.rb:

 belongs_to :post, :counter_cache => true

But I'm not sure how to do it with this many-to-many association. Any ideas?

alexchenco
  • 53,565
  • 76
  • 241
  • 413
  • possible duplicate of [Counter cache for a model with a many-to-many association](http://stackoverflow.com/questions/9595338/counter-cache-for-a-model-with-a-many-to-many-association) – Peter O. Dec 27 '12 at 16:05
  • @Peter Ha sorry, I can't believe I asked exactly the same question long ago. – alexchenco Dec 28 '12 at 09:59

1 Answers1

3

Use common :counter_cache option for tags. Despite the fact that it counts Taggings objects, which belongs_to (just one) post, this is what you looking for.

# tagging:

attr_accessible :tag_id, :post_id

belongs_to :post
belongs_to :tag, :counter_cache => :posts_count

validates_uniqueness_of :tag_id, :scope => :post_id

Validator will prevent the creation of several identical tags for the same posts, thus you can avoid duplicate records.

Valery Kvon
  • 4,438
  • 1
  • 20
  • 15