diff --git a/activerecord/lib/active_record/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb index 031918712a818d5dcea698ef5abcbddf16fff411..c9c46b8d4fbb84c57faa3e9cecf4c0af609be347 100644 --- a/activerecord/lib/active_record/counter_cache.rb +++ b/activerecord/lib/active_record/counter_cache.rb @@ -25,9 +25,10 @@ def reset_counters(id, *counters) self.name end + foreign_key = has_many_association.foreign_key.to_s child_class = has_many_association.klass belongs_to = child_class.reflect_on_all_associations(:belongs_to) - reflection = belongs_to.find { |e| e.class_name == expected_name } + reflection = belongs_to.find { |e| e.foreign_key.to_s == foreign_key } counter_name = reflection.counter_cache_column stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({ diff --git a/activerecord/test/cases/counter_cache_test.rb b/activerecord/test/cases/counter_cache_test.rb index 3ed96a3ec8a9a83cbf360cad19d36c78bb38b6dd..cd3d19e78318e3e0c22da9dfa3b2ac5577d0d7f4 100644 --- a/activerecord/test/cases/counter_cache_test.rb +++ b/activerecord/test/cases/counter_cache_test.rb @@ -6,9 +6,11 @@ require 'models/reply' require 'models/category' require 'models/categorization' +require 'models/dog' +require 'models/dog_lover' class CounterCacheTest < ActiveRecord::TestCase - fixtures :topics, :categories, :categorizations, :cars + fixtures :topics, :categories, :categorizations, :cars, :dogs, :dog_lovers class ::SpecialTopic < ::Topic has_many :special_replies, :foreign_key => 'parent_id' @@ -61,7 +63,7 @@ class ::SpecialReply < ::Reply end end - test "reset counter should with belongs_to which has class_name" do + test "reset counter with belongs_to which has class_name" do car = cars(:honda) assert_nothing_raised do Car.reset_counters(car.id, :engines) @@ -71,6 +73,20 @@ class ::SpecialReply < ::Reply end end + test "reset the right counter if two have the same class_name" do + david = dog_lovers(:david) + + DogLover.increment_counter(:bred_dogs_count, david.id) + DogLover.increment_counter(:trained_dogs_count, david.id) + + assert_difference 'david.reload.bred_dogs_count', -1 do + DogLover.reset_counters(david.id, :bred_dogs) + end + assert_difference 'david.reload.trained_dogs_count', -1 do + DogLover.reset_counters(david.id, :trained_dogs) + end + end + test "update counter with initial null value" do category = categories(:general) assert_equal 2, category.categorizations.count diff --git a/activerecord/test/fixtures/dog_lovers.yml b/activerecord/test/fixtures/dog_lovers.yml new file mode 100644 index 0000000000000000000000000000000000000000..d3e5e4a1aa9919be4477b5bdaf5c6cb500a54bd7 --- /dev/null +++ b/activerecord/test/fixtures/dog_lovers.yml @@ -0,0 +1,4 @@ +david: + id: 1 + bred_dogs_count: 0 + trained_dogs_count: 1 diff --git a/activerecord/test/fixtures/dogs.yml b/activerecord/test/fixtures/dogs.yml new file mode 100644 index 0000000000000000000000000000000000000000..16d19be2c506bb7797701c6c8b60be2d6b0b4b87 --- /dev/null +++ b/activerecord/test/fixtures/dogs.yml @@ -0,0 +1,3 @@ +sophie: + id: 1 + trainer_id: 1 diff --git a/activerecord/test/models/dog.rb b/activerecord/test/models/dog.rb new file mode 100644 index 0000000000000000000000000000000000000000..72b7d33a864b03d499a47531cca71384659f9b48 --- /dev/null +++ b/activerecord/test/models/dog.rb @@ -0,0 +1,4 @@ +class Dog < ActiveRecord::Base + belongs_to :breeder, :class_name => "DogLover", :counter_cache => :bred_dogs_count + belongs_to :trainer, :class_name => "DogLover", :counter_cache => :trained_dogs_count +end diff --git a/activerecord/test/models/dog_lover.rb b/activerecord/test/models/dog_lover.rb new file mode 100644 index 0000000000000000000000000000000000000000..a33dc575c59ad4c541c94e762054aa7e5d7552d6 --- /dev/null +++ b/activerecord/test/models/dog_lover.rb @@ -0,0 +1,4 @@ +class DogLover < ActiveRecord::Base + has_many :trained_dogs, :class_name => "Dog", :foreign_key => :trainer_id + has_many :bred_dogs, :class_name => "Dog", :foreign_key => :breeder_id +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 11378c12e5e4aaf50ba13b9302693f08adbccd77..e2cd7ce9e4d11b17ce02888a2404565367f055e9 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -213,6 +213,16 @@ def create_table(*args, &block) t.integer :access_level, :default => 1 end + create_table :dog_lovers, :force => true do |t| + t.integer :trained_dogs_count, :default => 0 + t.integer :bred_dogs_count, :default => 0 + end + + create_table :dogs, :force => true do |t| + t.integer :trainer_id + t.integer :breeder_id + end + create_table :edges, :force => true, :id => false do |t| t.column :source_id, :integer, :null => false t.column :sink_id, :integer, :null => false