Skip to content
Browse files

Implement ActiveRecord#reset_counter_cache

[#1211 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
1 parent de2cd8e commit 50c28e78c7aa40dc329facbe6131d657d5629bd4 @hardbap hardbap committed with jeremy May 20, 2009
Showing with 30 additions and 0 deletions.
  1. +2 −0 activerecord/CHANGELOG
  2. +18 −0 activerecord/lib/active_record/base.rb
  3. +10 −0 activerecord/test/cases/base_test.rb
View
2 activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*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]
* PostgreSQL: XML datatype support. #1874 [Leonardo Borges]
View
18 activerecord/lib/active_record/base.rb
@@ -967,6 +967,24 @@ def count_by_sql(sql)
connection.select_value(sql, "#{name} Count").to_i
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
# 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
View
10 activerecord/test/cases/base_test.rb
@@ -680,6 +680,16 @@ def test_decrement_counter
assert_equal -2, Topic.find(2).replies_count
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
category = categories(:general)
assert_nil category.categorizations_count

1 comment on commit 50c28e7

Please sign in to comment.
Something went wrong with that request. Please try again.