Method: ActiveRecord::CounterCache#update_counters
- Defined in:
- lib/active_record/counter_cache.rb
#update_counters(id, counters) ⇒ Object
A generic “counter updater” implementation, intended primarily to be used by increment_counter and decrement_counter, but which may also be useful on its own. It simply does a direct SQL update for the record with the given ID, altering the given hash of counters by the amount given by the corresponding value:
Parameters
-
id- The id of the object you wish to update a counter on or an Array of ids. -
counters- An Array of Hashes containing the names of the fields to update as keys and the amount to update the field by as values.
Examples
# For the Post with id of 5, decrement the comment_count by 1, and
# increment the action_count by 1
Post.update_counters 5, :comment_count => -1, :action_count => 1
# Executes the following SQL:
# UPDATE posts
# SET comment_count = COALESCE(comment_count, 0) - 1,
# action_count = COALESCE(action_count, 0) + 1
# WHERE id = 5
# For the Posts with id of 10 and 15, increment the comment_count by 1
Post.update_counters [10, 15], :comment_count => 1
# Executes the following SQL:
# UPDATE posts
# SET comment_count = COALESCE(comment_count, 0) + 1
# WHERE id IN (10, 15)
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/active_record/counter_cache.rb', line 75 def update_counters(id, counters) updates = counters.map do |counter_name, value| operator = value < 0 ? '-' : '+' quoted_column = connection.quote_column_name(counter_name) "#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}" end IdentityMap.remove_by_id(symbolized_base_class, id) if IdentityMap.enabled? update_all(updates.join(', '), primary_key => id ) end |