0

I've read on counter caches on associations.

Is there a way to easily implement (via a gem that will do the heavy lifting) of a counter cache for some condition? for example:

usually a counter cache would be

class User
  has_many :messages

class Message
  belongs_to :user, counter_cache: true

however, lets say that I don't want to count how many messages, but to count the total number of characters in all of the messages from Joe

so lets say I have a method count_chars_from(user) that returns the number of chars from a user

I want to update a specific column when many thing occur in the system (when joe sends a message to several people - all of those users need to be updated, when joe edits a message to one person, etc)

This could be done with observers I guess, but I see myself creating ugly code very quickly.

Is there a way to have something like the above?

Nick Ginanto
  • 31,090
  • 47
  • 134
  • 244

1 Answers1

0

Currently, there is no special methods/helpers for this. Rails doesn't support conditional counters.

However, you can simply define your own.

class Message
  belongs_to :user
  after_create :inc_counters
  after_destroy :dec_counters

  private
  def inc_counters
    if user && your_conditions
      user.increment(:conditional_counter)
    end
  end

  def dec_counters
    if user && your_conditions
      user.decrement(:conditional_counter)
    end
  end
end

I'd suggest take a look at counter_cache implementation. It looks pretty complex, but simple implementation works in one of my project pretty well.
Also consider to use update_column to not trigger validations and callbacks on User model.
And test you code when you delete parent model if it has dependent: :destroy on association.

cutalion
  • 4,334
  • 1
  • 38
  • 47