Permalink
Browse files

fix `reset_counters` to work even with complex class names

e.g. it guesses that a belongs_to association to Namespace::MyModel is
named "my_model", unlike before where it would look up an association
named "namespace::mymodel" and fail.
  • Loading branch information...
1 parent ef0591e commit 8be3e09fcfb26c181f458e8d3e333b3987bd5c4f @mislav mislav committed Apr 17, 2010
Showing with 30 additions and 2 deletions.
  1. +4 −2 activerecord/lib/active_record/base.rb
  2. +26 −0 activerecord/test/cases/counter_cache_test.rb
@@ -935,8 +935,9 @@ def count_by_sql(sql)
def reset_counters(id, *counters)
object = find(id)
counters.each do |association|
- child_class = reflect_on_association(association).klass
- counter_name = child_class.reflect_on_association(self.name.downcase.to_sym).counter_cache_column
+ child_class = reflect_on_association(association.to_sym).klass
+ belongs_name = self.name.demodulize.underscore.to_sym
+ counter_name = child_class.reflect_on_association(belongs_name).counter_cache_column
value = object.send(association).count
connection.update(<<-CMD, "#{name} UPDATE")
@@ -945,6 +946,7 @@ def reset_counters(id, *counters)
WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(object.id)}
CMD
end
+ return true
end
# A generic "counter updater" implementation, intended primarily to be
@@ -7,6 +7,14 @@
class CounterCacheTest < ActiveRecord::TestCase
fixtures :topics, :categories, :categorizations
+ class SpecialTopic < ::Topic
+ has_many :special_replies, :foreign_key => 'parent_id'
+ end
+
+ class SpecialReply < ::Reply
+ belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
+ end
+
test "increment counter" do
topic = Topic.find(1)
assert_difference 'topic.reload.replies_count' do
@@ -31,6 +39,24 @@ class CounterCacheTest < ActiveRecord::TestCase
Topic.reset_counters(topic.id, :replies)
end
end
+
+ test "reset counters with string argument" do
+ topic = Topic.find(1)
+ Topic.increment_counter('replies_count', topic.id)
+
+ assert_difference 'topic.reload.replies_count', -1 do
+ Topic.reset_counters(topic.id, 'replies')
+ end
+ end
+
+ test "reset counters with modularized and camelized classnames" do
+ special = SpecialTopic.create!(:title => 'Special')
+ SpecialTopic.increment_counter(:replies_count, special.id)
+
+ assert_difference 'special.reload.replies_count', -1 do
+ SpecialTopic.reset_counters(special.id, :special_replies)
+ end
+ end
test "update counter with initial null value" do
category = categories(:general)

0 comments on commit 8be3e09

Please sign in to comment.