Implement ActiveRecord#reset_counter_cache

[#1211 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
Mike Breen 2009-05-20 10:31:12 -04:00 committed by Jeremy Kemper
parent de2cd8e39f
commit 50c28e78c7
3 changed files with 30 additions and 0 deletions

View File

@ -1,5 +1,7 @@
*Edge* *Edge*
* Reset your Active Record counter caches with the reset_counter_cache class method. #1211 [Mike Breen]
* Remove support for SQLite 2. Please upgrade to SQLite 3+ or install the plugin from git://github.com/rails/sqlite2_adapter.git [Pratik Naik] * Remove support for SQLite 2. Please upgrade to SQLite 3+ or install the plugin from git://github.com/rails/sqlite2_adapter.git [Pratik Naik]
* PostgreSQL: XML datatype support. #1874 [Leonardo Borges] * PostgreSQL: XML datatype support. #1874 [Leonardo Borges]

View File

@ -967,6 +967,24 @@ module ActiveRecord #:nodoc:
connection.select_value(sql, "#{name} Count").to_i connection.select_value(sql, "#{name} Count").to_i
end end
# Reset a counter cache for all records.
#
# ==== Parameters
#
# * +association_name+ - The name of of the association counter cache to reset
#
# ==== Examples
# # For all Post records reset the comments_count
# Post.reset_counter_cache(:comments)
def reset_counter_cache(association)
child_class = reflect_on_association(association).klass
counter_name = child_class.reflect_on_association(self.name.downcase.to_sym).counter_cache_column
find_each do |object|
connection.update("UPDATE #{quoted_table_name} SET #{connection.quote_column_name(counter_name)} = #{object.send(association).count} WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(object.id)}", "#{name} UPDATE")
end
end
# A generic "counter updater" implementation, intended primarily to be # A generic "counter updater" implementation, intended primarily to be
# used by increment_counter and decrement_counter, but which may also # 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 # be useful on its own. It simply does a direct SQL update for the record

View File

@ -680,6 +680,16 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal -2, Topic.find(2).replies_count assert_equal -2, Topic.find(2).replies_count
end end
def test_reset_counter_cache
assert_equal 1, Topic.find(1).replies_count
Topic.increment_counter("replies_count", 1)
assert_equal 2, Topic.find(1).replies_count
Topic.reset_counter_cache(:replies)
assert_equal 1, Topic.find(1).replies_count
end
def test_update_counter def test_update_counter
category = categories(:general) category = categories(:general)
assert_nil category.categorizations_count assert_nil category.categorizations_count