Permalink
Browse files

reset_counter should work with non-traditional belongs_to and polymor…

…phic belongs_to

[#4984 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
1 parent 87f64ef commit 1e53404fe9c39ad0849894d73e431315be8c0bf0 Neeraj Singh committed with josevalim Jun 27, 2010
@@ -17,8 +17,14 @@ module CounterCache
def reset_counters(id, *counters)
object = find(id)
counters.each do |association|
- child_class = reflect_on_association(association.to_sym).klass
- belongs_name = self.name.demodulize.underscore.to_sym
+ has_many_association = reflect_on_association(association.to_sym)
+ polymorphic_class = has_many_association.options[:as]
+ child_class = has_many_association.klass
+ belongs_to = child_class.reflect_on_all_associations(:belongs_to)
+ belongs_to_association = belongs_to.detect do |e|
+ polymorphic_class.nil? ? (e.class_name == self.name) : (e.class_name.to_s.downcase == polymorphic_class.to_s.downcase)
+ end
+ belongs_name = belongs_to_association.name
counter_name = child_class.reflect_on_association(belongs_name).counter_cache_column
self.unscoped.where(arel_table[self.primary_key].eq(object.id)).arel.update({
@@ -103,4 +109,4 @@ def decrement_counter(counter_name, id)
update_counters(id, counter_name => -1)
end
end
-end
+end
@@ -1,17 +1,20 @@
require 'cases/helper'
require 'models/topic'
+require 'models/car'
+require 'models/wheel'
+require 'models/engine'
require 'models/reply'
require 'models/category'
require 'models/categorization'
class CounterCacheTest < ActiveRecord::TestCase
- fixtures :topics, :categories, :categorizations
+ fixtures :topics, :categories, :categorizations, :cars
- class SpecialTopic < ::Topic
+ class ::SpecialTopic < ::Topic
has_many :special_replies, :foreign_key => 'parent_id'
end
- class SpecialReply < ::Reply
+ class ::SpecialReply < ::Reply
belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
end
@@ -58,6 +61,16 @@ class SpecialReply < ::Reply
end
end
+ test "reset counter should with belongs_to which has class_name" do
+ car = cars(:honda)
+ assert_nothing_raised do
+ Car.reset_counters(car.id, :engines)
+ end
+ assert_nothing_raised do
+ Car.reset_counters(car.id, :wheels)
+ end
+ end
+
test "update counter with initial null value" do
category = categories(:general)
assert_equal 2, category.categorizations.count
@@ -0,0 +1,4 @@
+honda:
+ id: 1
+ name: honda
+ engines_count: 0
@@ -0,0 +1,4 @@
+class Car < ActiveRecord::Base
+ has_many :engines
+ has_many :wheels, :as => :wheelable
+end
@@ -0,0 +1,3 @@
+class Engine < ActiveRecord::Base
+ belongs_to :my_car, :class_name => 'Car', :foreign_key => 'car_id', :counter_cache => :engines_count
+end
@@ -0,0 +1,3 @@
+class Wheel < ActiveRecord::Base
+ belongs_to :wheelable, :polymorphic => true, :counter_cache => true
+end
@@ -82,6 +82,12 @@ def create_table(*args, &block)
t.string :name
end
+ create_table :cars, :force => true do |t|
+ t.string :name
+ t.integer :engines_count
+ t.integer :wheels_count
+ end
+
create_table :categories, :force => true do |t|
t.string :name, :null => false
t.string :type
@@ -179,6 +185,9 @@ def create_table(*args, &block)
end
add_index :edges, [:source_id, :sink_id], :unique => true, :name => 'unique_edge_index'
+ create_table :engines, :force => true do |t|
+ t.integer :car_id
+ end
create_table :entrants, :force => true do |t|
t.string :name, :null => false
@@ -566,6 +575,10 @@ def create_table(*args, &block)
t.integer :zine_id
end
+ create_table :wheels, :force => true do |t|
+ t.references :wheelable, :polymorphic => true
+ end
+
create_table :zines, :force => true do |t|
t.string :title
end

0 comments on commit 1e53404

Please sign in to comment.