123456789_123456789_123456789_123456789_123456789_

Module: Mongoid::Association::Referenced::CounterCache

Relationships & Source Files
Namespace Children
Modules:
Extension / Inclusion / Inheritance Descendants
Included In:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ActiveSupport::Concern
Defined in: lib/mongoid/association/referenced/counter_cache.rb

Overview

Mixin module included into ::Mongoid::Document which adds the ability to cache the count of opposite-side documents in referenced n-to-many associations.

Class Method Summary

Instance Method Summary

Class Method Details

.define_callbacks!(association) ⇒ Class

This method is for internal use only.

Add the callbacks responsible for update the counter cache field.

Examples:

Add the touchable.

Mongoid::Association::Referenced::CounterCache.define_callbacks!(association)

Parameters:

Returns:

  • (Class)

    The association’s owning class.

[ GitHub ]

  
# File 'lib/mongoid/association/referenced/counter_cache.rb', line 99

def self.define_callbacks!(association)
  name = association.name
  cache_column = association.counter_cache_column_name.to_sym

  association.inverse_class.tap do |klass|
    klass.after_update do
      foreign_key = association.foreign_key

      if send("#{foreign_key}_previously_changed?")
        original, current = send("#{foreign_key}_previous_change")

        unless original.nil?
          association.klass.with(persistence_context.for_child(association.klass)) do |_class|
            _class.decrement_counter(cache_column, original)
          end
        end

        if record = __send__(name)
          unless current.nil?
            record[cache_column] = (record[cache_column] || 0) + 1
            record.class.with(record.persistence_context) do |_class|
              _class.increment_counter(cache_column, current) if record.persisted?
            end
          end
        end
      end
    end

    klass.after_create do
      if record = __send__(name)
        record[cache_column] = (record[cache_column] || 0) + 1

        if record.persisted?
          record.class.with(record.persistence_context) do |_class|
            _class.increment_counter(cache_column, record._id)
          end
          record.remove_change(cache_column)
        end
      end
    end

    klass.before_destroy do
      if record = __send__(name)
        record[cache_column] = (record[cache_column] || 0) - 1 unless record.frozen?

        if record.persisted?
          record.class.with(record.persistence_context) do |_class|
            _class.decrement_counter(cache_column, record._id)
          end
          record.remove_change(cache_column)
        end
      end
    end
  end
end

Instance Method Details

#reset_counters(*counters)

Reset the given counter using the .count() query from the db. This method is useful in case that a counter got corrupted, or a new counter was added to the collection.

Examples:

Reset the given counter cache

post.reset_counters(:comments)

Parameters:

[ GitHub ]

  
# File 'lib/mongoid/association/referenced/counter_cache.rb', line 22

def reset_counters(*counters)
  self.class.with(persistence_context) do |_class|
    _class.reset_counters(self, *counters)
  end
end