diff options
Diffstat (limited to 'activerecord')
-rwxr-xr-x | activerecord/lib/active_record/base.rb | 19 | ||||
-rwxr-xr-x | activerecord/test/cases/base_test.rb | 7 |
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 |