wyc
wyc

Reputation: 55273

How do I use counter_cache in this many-to-many association?

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?

Upvotes: 1

Views: 523

Answers (1)

Valery Kvon
Valery Kvon

Reputation: 4496

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.

Upvotes: 3

Related Questions