Merge pull request #4487 from sarenji/fix-reset-counters
Fix bug where reset_counters resets the wrong counter cache.
This commit is contained in:
commit
5f07953f36
|
@ -25,9 +25,10 @@ module ActiveRecord
|
|||
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({
|
||||
|
|
|
@ -6,9 +6,11 @@ require 'models/engine'
|
|||
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 CounterCacheTest < ActiveRecord::TestCase
|
|||
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 CounterCacheTest < ActiveRecord::TestCase
|
|||
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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
david:
|
||||
id: 1
|
||||
bred_dogs_count: 0
|
||||
trained_dogs_count: 1
|
|
@ -0,0 +1,3 @@
|
|||
sophie:
|
||||
id: 1
|
||||
trainer_id: 1
|
|
@ -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
|
|
@ -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
|
|
@ -213,6 +213,16 @@ ActiveRecord::Schema.define do
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue