instance method
update_counters
Ruby on Rails 5.2.8.1
Since v4.0.13Signature
update_counters(id, counters)
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- A Hash containing the names of the fields to update as keys and the amount to update the field by as values. -
:touchoption - Touch timestamp columns when updating. If attribute names are passed, they are updated along with updated_at/on attributes.
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) # For the Posts with id of 10 and 15, increment the comment_count by 1 # and update the updated_at value for each counter. Post.update_counters [10, 15], comment_count: 1, touch: true # Executes the following SQL: # UPDATE posts # SET comment_count = COALESCE(comment_count, 0) + 1, # `updated_at` = '2016-10-13T09:59:23-05:00' # WHERE id IN (10, 15)
Parameters
-
idreq -
countersreq
Source
# File activerecord/lib/active_record/counter_cache.rb, line 104
def update_counters(id, counters)
touch = counters.delete(:touch)
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
if touch
names = touch if touch != true
touch_updates = touch_attributes_with_time(*names)
updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
end
if id.is_a?(Relation) && self == id.klass
relation = id
else
relation = unscoped.where!(primary_key => id)
end
relation.update_all updates.join(", ")
end
Defined in activerecord/lib/active_record/counter_cache.rb line 104
· View on GitHub
· Improve this page
· Find usages on GitHub
Defined in ActiveRecord::CounterCache::ClassMethods