提交 5f07953f 编写于 作者: A Aaron Patterson

Merge pull request #4487 from sarenji/fix-reset-counters

Fix bug where reset_counters resets the wrong counter cache.
......@@ -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({
......
......@@ -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
......
david:
id: 1
bred_dogs_count: 0
trained_dogs_count: 1
sophie:
id: 1
trainer_id: 1
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
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 @@ 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册