aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xactiverecord/lib/active_record/base.rb19
-rwxr-xr-xactiverecord/test/cases/base_test.rb7
2 files changed, 24 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 8db3909d9a..479296ebae 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -927,7 +927,7 @@ module ActiveRecord #:nodoc:
#
# ==== Parameters
#
- # * +id+ - The id of the object you wish to update a counter on.
+ # * +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.
#
@@ -941,12 +941,27 @@ module ActiveRecord #:nodoc:
# # SET comment_count = comment_count - 1,
# # action_count = action_count + 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 = comment_count + 1,
+ # # WHERE id IN (10, 15)
def update_counters(id, counters)
updates = counters.inject([]) { |list, (counter_name, increment)|
sign = increment < 0 ? "-" : "+"
list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
}.join(", ")
- update_all(updates, "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}")
+
+ if id.is_a?(Array)
+ ids_list = id.map {|i| quote_value(i)}.join(', ')
+ condition = "IN (#{ids_list})"
+ else
+ condition = "= #{quote_value(id)}"
+ end
+
+ update_all(updates, "#{connection.quote_column_name(primary_key)} #{condition}")
end
# Increment a number field by one, usually representing a count.
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 0f03dae829..973bb567bd 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -639,6 +639,13 @@ class BasicsTest < ActiveRecord::TestCase
category.reload
assert_not_nil category.categorizations_count
assert_equal 4, category.categorizations_count
+
+ category_2 = categories(:technology)
+ count_1, count_2 = (category.categorizations_count || 0), (category_2.categorizations_count || 0)
+ Category.update_counters([category.id, category_2.id], "categorizations_count" => 2)
+ category.reload; category_2.reload
+ assert_equal count_1 + 2, category.categorizations_count
+ assert_equal count_2 + 2, category_2.categorizations_count
end
def test_update_all