module CounterCulture::Extensions::ClassMethods
Public Instance Methods
after_commit_counter_cache()
click to toggle source
this holds all configuration data
# File lib/counter_culture/extensions.rb, line 7 def after_commit_counter_cache config = @after_commit_counter_cache || [] if superclass.respond_to?(:after_commit_counter_cache) && superclass.after_commit_counter_cache config = superclass.after_commit_counter_cache + config end config end
counter_culture(relation, options = {})
click to toggle source
called to configure counter caches
# File lib/counter_culture/extensions.rb, line 16 def counter_culture(relation, options = {}) unless @after_commit_counter_cache # initialize callbacks only once after_create :_update_counts_after_create before_destroy :_update_counts_after_destroy, unless: :destroyed_for_counter_culture? if respond_to?(:before_real_destroy) && instance_methods.include?(:paranoia_destroyed?) before_real_destroy :_update_counts_after_destroy, if: -> (model) { !model.paranoia_destroyed? } end after_update :_update_counts_after_update, unless: :destroyed_for_counter_culture? if respond_to?(:before_restore) before_restore :_update_counts_after_create, if: -> (model) { model.deleted? } end if defined?(Discard::Model) && include?(Discard::Model) before_discard :_update_counts_after_destroy, if: ->(model) { !model.discarded? } before_undiscard :_update_counts_after_create, if: ->(model) { model.discarded? } end # we keep a list of all counter caches we must maintain @after_commit_counter_cache = [] end if options[:column_names] && !options[:column_names].is_a?(Hash) raise ":column_names must be a Hash of conditions and column names" end # add the counter to our collection @after_commit_counter_cache << Counter.new(self, relation, options) end
counter_culture_fix_counts(options = {})
click to toggle source
checks all of the declared counter caches on this class for correctnes based on original data; if the counter cache is incorrect, sets it to the correct count
options:
{ :exclude => list of relations to skip when fixing counts, :only => only these relations will have their counts fixed, :column_name => only this column will have its count fixed }
returns: a list of fixed record as an array of hashes of the form:
{ :entity => which model the count was fixed on, :id => the id of the model that had the incorrect count, :what => which column contained the incorrect count, :wrong => the previously saved, incorrect count, :right => the newly fixed, correct count }
# File lib/counter_culture/extensions.rb, line 71 def counter_culture_fix_counts(options = {}) raise "No counter cache defined on #{name}" unless @after_commit_counter_cache options[:exclude] = Array(options[:exclude]) if options[:exclude] options[:exclude] = options[:exclude].try(:map) {|x| x.is_a?(Enumerable) ? x : [x] } options[:only] = [options[:only]] if options[:only] && !options[:only].is_a?(Enumerable) options[:only] = options[:only].try(:map) {|x| x.is_a?(Enumerable) ? x : [x] } @after_commit_counter_cache.flat_map do |counter| next if options[:exclude] && options[:exclude].include?(counter.relation) next if options[:only] && !options[:only].include?(counter.relation) reconciler_options = %i(batch_size column_name finish skip_unsupported start touch verbose where) reconciler = CounterCulture::Reconciler.new(counter, options.slice(*reconciler_options)) reconciler.reconcile! reconciler.changes end.compact end