Dudo
Dudo

Reputation: 4169

summing together counter_caches

So... I have 3 models.

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar < ActiveRecord::Base
  belongs_to :foo
  has_many :bazs
end

class Baz < ActiveRecord::Base
  belongs_to :bar, counter_cache: true
end

So, I'd like a column for my Foo that behaves like a bars_count, except I want to add the bazs_count of Bar together, instead of the .size. Do I have to go manual here, with a before_save or something? Is there something with this functionality already in Rails?

So, if there are 2 bars... 1 has a bazs_count = 4, and another with bazs_count = 8. If both of those bars belong to a foo, I'd like to have bars_count = 12 whenever the bazs_count changes.

Reason being... I'll often be checking how many bazs a particular foo has, and I'd like to keep the querying minimal.

Upvotes: 2

Views: 45

Answers (1)

Sam
Sam

Reputation: 3067

You could add the following methods to your Baz model to increment and decrement the bazs_count column in your Foo model. I found that Rails pluralises baz to bazs, not bazes.

class Foo < ActiveRecord::Base
  has_many :bars
end

class Bar < ActiveRecord::Base
  belongs_to :foo, counter_cache: true
  has_many :bazs
end

class Baz < ActiveRecord::Base
  belongs_to :bar, counter_cache: true

  after_create :increment_foo_counter
  after_destroy :decrement_foo_counter

  private

  def increment_foo_counter
    Foo.increment_counter(:bazs_count, bar.foo_id)
  end

  def decrement_foo_counter
    Foo.decrement_counter(:bazs_count, bar.foo_id)
  end
end

Upvotes: 1

Related Questions