module CounterCacheWithConditions::ActiveRecord::InstanceMethods

Private Instance Methods

ccwc_update_counter_on(klass, foreign_key, counter_name, value, value_was = 0) click to toggle source

e.g. increment counter on association, and decrement it on old association if association was changed, and vice versa @param value (+1, -1) @param value_was value for old association (if association was changed)

# File lib/counter_cache_with_conditions/active_record.rb, line 88
def ccwc_update_counter_on(klass, foreign_key, counter_name, value, value_was = 0)
  association_id = send(foreign_key)
  klass.update_counters(association_id, counter_name => value) if association_id
  if value_was != 0
    association_was = attribute_was(foreign_key.to_s)
    klass.update_counters(association_was, counter_name => value_was) if association_was && association_was != association_id
  end
end
counter_cache_with_conditions_after_create() click to toggle source
# File lib/counter_cache_with_conditions/active_record.rb, line 30
def counter_cache_with_conditions_after_create
  self.counter_cache_with_conditions_options.each do |klass, foreign_key, counter_name, conditions|
    if counter_conditions_match?(conditions)
      association_id = send(foreign_key)
      klass.increment_counter(counter_name, association_id) if association_id
    end
  end
end
counter_cache_with_conditions_before_destroy() click to toggle source
# File lib/counter_cache_with_conditions/active_record.rb, line 57
def counter_cache_with_conditions_before_destroy
  self.counter_cache_with_conditions_options.each do |klass, foreign_key, counter_name, conditions|
    if counter_conditions_without_changes_match?(conditions)
      association_was = attribute_was(foreign_key.to_s)
      klass.decrement_counter(counter_name, association_was) if association_was
    end
  end
end
counter_cache_with_conditions_before_update() click to toggle source
# File lib/counter_cache_with_conditions/active_record.rb, line 39
def counter_cache_with_conditions_before_update
  self.counter_cache_with_conditions_options.each do |klass, foreign_key, counter_name, conditions|
    match_before = counter_conditions_without_changes_match?(conditions)
    match_now = counter_conditions_match?(conditions)
    if match_now && !match_before
      ccwc_update_counter_on(klass, foreign_key, counter_name, 1, 0)
    elsif !match_now && match_before && send("#{foreign_key}_changed?")
      # decrement only old, if association changed and condition broken
      ccwc_update_counter_on(klass, foreign_key, counter_name, 0, -1)
    elsif !match_now && match_before
      ccwc_update_counter_on(klass, foreign_key, counter_name, -1, -1)
    elsif match_now && send("#{foreign_key}_changed?")
      # if just association changed, decrement old, increment new
      ccwc_update_counter_on(klass, foreign_key, counter_name, 1, -1)
    end
  end
end
counter_conditions_match?(conditions) click to toggle source
# File lib/counter_cache_with_conditions/active_record.rb, line 67
def counter_conditions_match?(conditions)
  if conditions.is_a? Array
    attr_names, block = conditions
    block.call(*attr_names.map { |attr| send(attr) })
  else
    conditions.all? { |attr, value| send(attr) == value }
  end
end
counter_conditions_without_changes_match?(conditions) click to toggle source
# File lib/counter_cache_with_conditions/active_record.rb, line 76
def counter_conditions_without_changes_match?(conditions)
  if conditions.is_a? Array
    attr_names, block = conditions
    block.call(*attr_names.map { |attr| attribute_was(attr.to_s) })
  else
    conditions.all? { |attr, value| attribute_was(attr.to_s) == value }
  end
end