Question

I have a Forum model which has many discussions. Each discussion has many posts. Discussion is more or less just a collection of post objects.

Now I'd like to have a counter_cache available in Forum for the posts contained in that forums discussions.

So really, it seems like I should be using a :through association instead of two separate associations to accomplish this.

However I can't find any reference that suggest mixing a has_many :through and has_one :through association, just for one-to-one and many-to-many, not for one-to-many.

class Forum < ActiveRecord::Base
  has_many :discussions
  has_many :posts, :through => :discussions
end

class Post < ActiveRecord::Base
  belongs_to :discussion
  has_one :forum, :through => discussion
end

class Discussion < ActiveRecord::Base
  has_many :posts
  belongs_to :forum
end

Is something like the above advisable, or should I just handle the counter cache manually?

Was it helpful?

Solution 2

So the normal counter cache seems to be working just fine, as does mixing the relationship types

class Post < ActiveRecord::Base
  belongs_to :user
  belongs_to :discussion
  has_one :forum, :through => :discussion,
            :counter_cache => :posts_counter
end
class Forum < ActiveRecord::Base
  has_many :discussions
  has_many :posts, :through => :discussions
end

class Discussion < ActiveRecord::Base
  has_many :posts
  belongs_to :forum
  belongs_to :user
end

OTHER TIPS

Something like this should work.

class Forum < ActiveRecord::Base
  has_many :discussions
  has_many :posts, :through => :discussions
end

class Post < ActiveRecord::Base
  belongs_to :discussion, counter_cache: true
  has_one :forum, :through => discussion

  after_create :increment_forum_counter_cache

  private

  def increment_forum_counter_cache
     Forum.increment_counter( 'discussions_count', self.discussion.forum.id )
  end
end

class Discussion < ActiveRecord::Base
  has_many :posts
  belongs_to :forum

end

I seem to remember having trouble setting up counter_cache through a has_one relationship previously. The method above should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top