module Mongoid::Relations::CounterCache::ClassMethods
Public Instance Methods
Decrement the counter name from the entries that match the id by one. This method is used on associations callbacks when counter_cache is enabled
@example Decrement comments counter
Post.decrement_counter(:comments_count, '50e0edd97c71c17ea9000001')
@param [ Symbol
] Counter cache name @param [ String ] The id of the object that will have its counter decremented.
@since 3.1.0
# File lib/mongoid/relations/counter_cache.rb, line 88 def decrement_counter(counter_name, id) update_counters(id, counter_name.to_sym => -1) end
Increment the counter name from the entries that match the id by one. This method is used on associations callbacks when counter_cache is enabled
@example Increment comments counter
Post.increment_counter(:comments_count, '50e0edd97c71c17ea9000001')
@param [ Symbol
] Counter cache name @param [ String ] The id of the object that will have its counter incremented.
@since 3.1.0
# File lib/mongoid/relations/counter_cache.rb, line 73 def increment_counter(counter_name, id) update_counters(id, counter_name.to_sym => 1) end
Reset the given counter using the .count() query from the db. This method is usuful in case that a counter got corrupted, or a new counter was added to the collection.
@example Reset the given counter cache
Post.reset_counters('50e0edd97c71c17ea9000001', :comments)
@param [ String ] The id of the object that will be reset. @param [ Symbol
, Array ] One
or more counter caches to reset
@since 3.1.0
# File lib/mongoid/relations/counter_cache.rb, line 36 def reset_counters(id, *counters) document = id.is_a?(Document) ? id : find(id) counters.each do |name| meta = reflect_on_association(name) inverse = meta.klass.reflect_on_association(meta.inverse) counter_name = inverse.counter_cache_column_name document.update_attribute(counter_name, document.send(name).count) end end
Update the given counters by the value factor. It uses the atomic $inc command.
@example Add 5 to comments counter and remove 2 from likes
counter. Post.update_counters('50e0edd97c71c17ea9000001', :comments_count => 5, :likes_count => -2)
@param [ String ] The id of the object to update. @param [ Hash ] Key = counter_cache and Value = factor.
@since 3.1.0
# File lib/mongoid/relations/counter_cache.rb, line 58 def update_counters(id, counters) where(:_id => id).inc(counters) end
Private Instance Methods
Add the callbacks responsible for update the counter cache field
@api private
@example Add the touchable.
Person.add_counter_cache_callbacks(meta)
@param [ Metadata
] metadata The metadata for the relation.
@since 3.1.0
# File lib/mongoid/relations/counter_cache.rb, line 104 def add_counter_cache_callbacks(meta) name = meta.name cache_column = meta.counter_cache_column_name.to_sym after_update do if record = __send__(name) foreign_key = meta.foreign_key if attribute_changed?(foreign_key) original, current = attribute_change(foreign_key) unless original.nil? record.class.with(persistence_context) do |_class| _class.decrement_counter(cache_column, original) end end 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 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 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