reset_counter should work with non-traditional belongs_to and polymorphic belongs_to

[#4984 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
This commit is contained in:
Neeraj Singh
2010-06-27 11:17:44 -04:00
committed by José Valim
parent 87f64ef05e
commit 1e53404fe9
7 changed files with 52 additions and 6 deletions

View File

@@ -17,8 +17,14 @@ module ActiveRecord
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 @@ module ActiveRecord
update_counters(id, counter_name => -1)
end
end
end
end

View File

@@ -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 CounterCacheTest < ActiveRecord::TestCase
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

4
activerecord/test/fixtures/cars.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
honda:
id: 1
name: honda
engines_count: 0

View File

@@ -0,0 +1,4 @@
class Car < ActiveRecord::Base
has_many :engines
has_many :wheels, :as => :wheelable
end

View File

@@ -0,0 +1,3 @@
class Engine < ActiveRecord::Base
belongs_to :my_car, :class_name => 'Car', :foreign_key => 'car_id', :counter_cache => :engines_count
end

View File

@@ -0,0 +1,3 @@
class Wheel < ActiveRecord::Base
belongs_to :wheelable, :polymorphic => true, :counter_cache => true
end

View File

@@ -82,6 +82,12 @@ ActiveRecord::Schema.define do
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 @@ ActiveRecord::Schema.define do
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 @@ ActiveRecord::Schema.define do
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