aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-21 14:10:33 -0300
committerRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-21 14:36:04 -0300
commit648c5a1369ed64608c3ca43a5ebc917687d20010 (patch)
tree834ad77d7aec2718cb6148e6ec6cd0a42a9012fc
parentc091fae21f32250b19475f124c3b680dbbc163d9 (diff)
downloadrails-648c5a1369ed64608c3ca43a5ebc917687d20010.tar.gz
rails-648c5a1369ed64608c3ca43a5ebc917687d20010.tar.bz2
rails-648c5a1369ed64608c3ca43a5ebc917687d20010.zip
Merge pull request #5210 from Pliny/masteri
Fix for #5200 Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/counter_cache.rb
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/counter_cache.rb2
-rw-r--r--activerecord/test/cases/counter_cache_test.rb11
-rw-r--r--activerecord/test/fixtures/friendships.yml4
-rw-r--r--activerecord/test/fixtures/people.yml3
-rw-r--r--activerecord/test/models/friendship.rb4
-rw-r--r--activerecord/test/models/person.rb2
-rw-r--r--activerecord/test/schema/schema.rb6
8 files changed, 36 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 6f81625429..ebb4613cdd 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,11 @@
## Rails 3.2.9 (unreleased)
+* Fix `reset_counters` when there are multiple `belongs_to` association with the
+ same foreign key and one of them have a counter cache.
+ Fixes #5200.
+
+ *Dave Desrochers*
+
* Round usec when comparing timestamp attributes in the dirty tracking.
Fixes #6975.
diff --git a/activerecord/lib/active_record/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb
index ee0b0c7fab..0ba54e6248 100644
--- a/activerecord/lib/active_record/counter_cache.rb
+++ b/activerecord/lib/active_record/counter_cache.rb
@@ -28,7 +28,7 @@ module ActiveRecord
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.foreign_key.to_s == foreign_key }
+ reflection = belongs_to.find { |e| e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
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 cd3d19e783..ee443741ca 100644
--- a/activerecord/test/cases/counter_cache_test.rb
+++ b/activerecord/test/cases/counter_cache_test.rb
@@ -8,9 +8,11 @@ require 'models/category'
require 'models/categorization'
require 'models/dog'
require 'models/dog_lover'
+require 'models/person'
+require 'models/friendship'
class CounterCacheTest < ActiveRecord::TestCase
- fixtures :topics, :categories, :categorizations, :cars, :dogs, :dog_lovers
+ fixtures :topics, :categories, :categorizations, :cars, :dogs, :dog_lovers, :people, :friendships
class ::SpecialTopic < ::Topic
has_many :special_replies, :foreign_key => 'parent_id'
@@ -109,4 +111,11 @@ class CounterCacheTest < ActiveRecord::TestCase
Topic.update_counters([t1.id, t2.id], :replies_count => 2)
end
end
+
+ test "reset the right counter if two have the same foreign key" do
+ michael = people(:michael)
+ assert_nothing_raised(ActiveRecord::StatementInvalid) do
+ Person.reset_counters(michael.id, :followers)
+ end
+ end
end
diff --git a/activerecord/test/fixtures/friendships.yml b/activerecord/test/fixtures/friendships.yml
new file mode 100644
index 0000000000..1ee09175bf
--- /dev/null
+++ b/activerecord/test/fixtures/friendships.yml
@@ -0,0 +1,4 @@
+Connection 1:
+ id: 1
+ person_id: 1
+ friend_id: 2 \ No newline at end of file
diff --git a/activerecord/test/fixtures/people.yml b/activerecord/test/fixtures/people.yml
index 123673a2af..e640a38f1f 100644
--- a/activerecord/test/fixtures/people.yml
+++ b/activerecord/test/fixtures/people.yml
@@ -4,15 +4,18 @@ michael:
primary_contact_id: 2
number1_fan_id: 3
gender: M
+ followers_count: 1
david:
id: 2
first_name: David
primary_contact_id: 3
number1_fan_id: 1
gender: M
+ followers_count: 1
susan:
id: 3
first_name: Susan
primary_contact_id: 2
number1_fan_id: 1
gender: F
+ followers_count: 1
diff --git a/activerecord/test/models/friendship.rb b/activerecord/test/models/friendship.rb
new file mode 100644
index 0000000000..6b4f7acc38
--- /dev/null
+++ b/activerecord/test/models/friendship.rb
@@ -0,0 +1,4 @@
+class Friendship < ActiveRecord::Base
+ belongs_to :friend, class_name: 'Person'
+ belongs_to :follower, foreign_key: 'friend_id', class_name: 'Person', counter_cache: :followers_count
+end
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index dcfea3170c..a64405b246 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -7,6 +7,8 @@ class Person < ActiveRecord::Base
has_many :secure_posts, :through => :secure_readers
has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null'
+ has_many :followers, foreign_key: 'friend_id', class_name: 'Friendship'
+
has_many :references
has_many :bad_references
has_many :fixed_bad_references, :conditions => { :favourite => true }, :class_name => 'BadReference'
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 2b7ea0ce34..b3ae2abbc4 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -265,6 +265,11 @@ ActiveRecord::Schema.define do
t.string :name
end
+ create_table :friendships, :force => true do |t|
+ t.integer :friend_id
+ t.integer :person_id
+ end
+
create_table :goofy_string_id, :force => true, :id => false do |t|
t.string :id, :null => false
t.string :info
@@ -465,6 +470,7 @@ ActiveRecord::Schema.define do
t.references :number1_fan
t.integer :lock_version, :null => false, :default => 0
t.string :comments
+ t.integer :followers_count, :default => 0
t.references :best_friend
t.references :best_friend_of
t.timestamps