Search code examples
ruby-on-railscachingaasmcounter-cache

Multiple counter cache columns with aasm


I am looking for a way to cache the number of each state. I have done counter caching before, but is there a way to create multiple counter_cache columns for each state and keep them updated or should I look elsewhere for caching these values.

aasm_column :state
aasm_initial_state :unopened

aasm_state :unopened
aasm_state :contacted
aasm_state :closed

aasm_event :contact do
  transitions :to => :contacted, :from => [:unopened] 
end

aasm_event :close do
  transitions :to => :closed, :from => [:contacted] 
end

It seems like it would just be 3 columns in the database. Any ideas?


Solution

  • You would have to do three columns, one for each state, but write logic manually to increment/decrement those counters, using dirty object functionality. Rails doesn't provide any automatic logic in save to do this.

    So in the model being counted:

    after_create :increment_counter
    after_save :update_counters
    after_destroy :decrement_counter
    
    def increment_counter
      self.parent.increment("#{self.state}_counter")
    end
    
    def decrement_counter
      self.parent.decrement("#{self.state}_counter")
    end
    
    def update_counters
      return unless self.state_changed?
      self.parent.decrement("#{self.state_was}_counter")
      self.parent.increment("#{self.state}_counter")
    end
    

    (This code is untested, but this is the basic idea)