Module: ConcernsOnRails::Models::CounterCacheable::ClassMethods

Defined in:
lib/concerns_on_rails/models/counter_cacheable.rb

Instance Method Summary collapse

Instance Method Details

#counter_cacheable_by(association, count: nil, touch: false, **options) ⇒ Object

Declare one counter. Repeatable — each call maintains another column (rules accumulate, reassigned never mutated, so subclasses inherit). ‘count:` defaults to “<table_name>_count” (e.g. comments → comments_count).

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/concerns_on_rails/models/counter_cacheable.rb', line 72

def counter_cacheable_by(association, count: nil, touch: false, **options)
  association = association.to_sym
  condition = options[:if]
  extra = options.keys - [:if]
  raise ArgumentError, "#{LABEL}: unknown option(s): #{extra.join(', ')}" unless extra.empty?

  reflection = reflect_on_association(association)
  validate_counter_cacheable!(association, reflection, condition, touch)

  count_column = (count || "#{table_name}_count").to_sym
  counter_cacheable_ensure_parent_column!(reflection, count_column)

  self.counter_cacheable_rules = counter_cacheable_rules + [{
    association: association, count_column: count_column,
    condition: condition, touch: touch ? true : false
  }]
end

#recount_counter_caches!(only_association = nil) ⇒ Object

Recompute every (or one) counter from scratch — drift repair / backfill. Returns { count_column => parents_with_a_nonzero_count }.



92
93
94
95
96
97
98
99
# File 'lib/concerns_on_rails/models/counter_cacheable.rb', line 92

def recount_counter_caches!(only_association = nil)
  rules = counter_cacheable_rules
  rules = rules.select { |r| r[:association] == only_association.to_sym } if only_association

  rules.to_h do |rule|
    [rule[:count_column], counter_cacheable_recount_rule(rule)]
  end
end