Skip to content
This repository
Browse code

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...
commit bc84bd17d1f981ca4899f336f6b94e552bc6a058 1 parent bfca7d7
Mislav Marohnić mislav authored
10 activerecord/lib/active_record/counter_cache.rb
@@ -16,13 +16,15 @@ module CounterCache
16 16 def reset_counters(id, *counters)
17 17 object = find(id)
18 18 counters.each do |association|
19   - child_class = reflect_on_association(association).klass
20   - counter_name = child_class.reflect_on_association(self.name.downcase.to_sym).counter_cache_column
  19 + child_class = reflect_on_association(association.to_sym).klass
  20 + belongs_name = self.name.demodulize.underscore.to_sym
  21 + counter_name = child_class.reflect_on_association(belongs_name).counter_cache_column
21 22
22   - self.unscoped.where(arel_table[self.primary_key].eq(object.id)).arel.update(
  23 + self.unscoped.where(arel_table[self.primary_key].eq(object.id)).arel.update({
23 24 arel_table[counter_name] => object.send(association).count
24   - )
  25 + })
25 26 end
  27 + return true
26 28 end
27 29
28 30 # A generic "counter updater" implementation, intended primarily to be
25 activerecord/test/cases/counter_cache_test.rb
@@ -7,6 +7,14 @@
7 7 class CounterCacheTest < ActiveRecord::TestCase
8 8 fixtures :topics, :categories, :categorizations
9 9
  10 + class SpecialTopic < ::Topic
  11 + has_many :special_replies, :foreign_key => 'parent_id'
  12 + end
  13 +
  14 + class SpecialReply < ::Reply
  15 + belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
  16 + end
  17 +
10 18 setup do
11 19 @topic = Topic.find(1)
12 20 end
@@ -32,6 +40,23 @@ class CounterCacheTest < ActiveRecord::TestCase
32 40 Topic.reset_counters(@topic.id, :replies)
33 41 end
34 42 end
  43 +
  44 + test "reset counters with string argument" do
  45 + Topic.increment_counter('replies_count', @topic.id)
  46 +
  47 + assert_difference '@topic.reload.replies_count', -1 do
  48 + Topic.reset_counters(@topic.id, 'replies')
  49 + end
  50 + end
  51 +
  52 + test "reset counters with modularized and camelized classnames" do
  53 + special = SpecialTopic.create!(:title => 'Special')
  54 + SpecialTopic.increment_counter(:replies_count, special.id)
  55 +
  56 + assert_difference 'special.reload.replies_count', -1 do
  57 + SpecialTopic.reset_counters(special.id, :special_replies)
  58 + end
  59 + end
35 60
36 61 test "update counter with initial null value" do
37 62 category = categories(:general)

0 comments on commit bc84bd1

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