diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index cec876149c1..362f1053cd4 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -344,8 +344,12 @@ module ActiveRecord if options[:counter_sql] interpolate(options[:counter_sql]) else - # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */ - interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" } + # replace the SELECT clause with COUNT(SELECTS), preserving any hints within /* ... */ + interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) do + count_with = $2.to_s + count_with = '*' if count_with.blank? || count_with =~ /,/ + "SELECT #{$1}COUNT(#{count_with}) FROM" + end end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index cddd2a6f8cc..a60af7c0464 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -41,6 +41,21 @@ class HasManyAssociationsTestForCountWithCountSql < ActiveRecord::TestCase end end +class HasManyAssociationsTestForCountDistinctWithFinderSql < ActiveRecord::TestCase + class Invoice < ActiveRecord::Base + has_many :custom_line_items, :class_name => 'LineItem', :finder_sql => "SELECT DISTINCT line_items.amount from line_items" + end + + def test_should_count_distinct_results + invoice = Invoice.new + invoice.custom_line_items << LineItem.new(:amount => 0) + invoice.custom_line_items << LineItem.new(:amount => 0) + invoice.save! + + assert_equal 1, invoice.custom_line_items.count + end +end + class HasManyAssociationsTest < ActiveRecord::TestCase