aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb12
-rw-r--r--activerecord/test/associations/join_model_test.rb9
3 files changed, 22 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index b0c3a3179e..9372adb583 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*2.0.0 [Preview Release]* (September 29th, 2007) [Includes duplicates of changes from 1.14.2 - 1.15.3]
+* Make size for has_many :through use counter cache if it exists. Closes #9734 [xaviershay]
+
* Remove DB2 adapter since IBM chooses to maintain their own adapter instead. [Jeremy Kemper]
* Extract Oracle, SQLServer, and Sybase adapters into gems. [Jeremy Kemper]
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index de0d7cc8a9..62839c4637 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -100,7 +100,9 @@ module ActiveRecord
# calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero
# and you need to fetch that collection afterwards, it'll take one less SELECT query if you use length.
def size
- loaded? ? @target.size : count
+ return @owner.send(:read_attribute, cached_counter_attribute_name) if has_cached_counter?
+ return @target.size if loaded?
+ return count
end
# Calculate sum using SQL, not Enumerable
@@ -258,6 +260,14 @@ module ActiveRecord
end
alias_method :sql_conditions, :conditions
+
+ def has_cached_counter?
+ @owner.attribute_present?(cached_counter_attribute_name)
+ end
+
+ def cached_counter_attribute_name
+ "#{@reflection.name}_count"
+ end
end
end
end
diff --git a/activerecord/test/associations/join_model_test.rb b/activerecord/test/associations/join_model_test.rb
index d18c878733..d92a0c760a 100644
--- a/activerecord/test/associations/join_model_test.rb
+++ b/activerecord/test/associations/join_model_test.rb
@@ -457,6 +457,15 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
assert !author.comments.loaded?
end
+ uses_mocha('has_many_through_collection_size_uses_counter_cache_if_it_exists') do
+ def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
+ author = authors(:david)
+ author.stubs(:read_attribute).with('comments_count').returns(100)
+ assert_equal 100, author.comments.size
+ assert !author.comments.loaded?
+ end
+ end
+
def test_adding_junk_to_has_many_through_should_raise_type_mismatch
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
end