From 9703959b5da7167f9ec92ab1eda49675ba951a34 Mon Sep 17 00:00:00 2001 From: Marcelo Giorgi Date: Fri, 1 Oct 2010 08:27:02 -0300 Subject: [PATCH] Honor distinct option when used with count operation after group clause [#5721 state:resolved] --- .../lib/active_record/relation/calculations.rb | 12 ++++++++---- activerecord/test/cases/calculations_test.rb | 9 +++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index d79ef78..3519880 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -177,7 +177,7 @@ module ActiveRecord distinct = options[:distinct] || distinct if @group_values.any? - execute_grouped_calculation(operation, column_name) + execute_grouped_calculation(operation, column_name, distinct) else execute_simple_calculation(operation, column_name, distinct) end @@ -191,19 +191,23 @@ module ActiveRecord end end + def operation_over_aggregate_column(column, operation, distinct) + operation == 'count' ? column.count(distinct) : column.send(operation) + end + def execute_simple_calculation(operation, column_name, distinct) #:nodoc: column = aggregate_column(column_name) # Postgresql doesn't like ORDER BY when there are no GROUP BY relation = except(:order) - select_value = operation == 'count' ? column.count(distinct) : column.send(operation) + select_value = operation_over_aggregate_column(column, operation, distinct) relation.select_values = [select_value] type_cast_calculated_value(@klass.connection.select_value(relation.to_sql), column_for(column_name), operation) end - def execute_grouped_calculation(operation, column_name) #:nodoc: + def execute_grouped_calculation(operation, column_name, distinct) #:nodoc: group_attr = @group_values.first association = @klass.reflect_on_association(group_attr.to_sym) associated = association && association.macro == :belongs_to # only count belongs_to associations @@ -221,7 +225,7 @@ module ActiveRecord relation = except(:group).group(group) relation.select_values = [ - aggregate_column(column_name).send(operation).as(aggregate_alias), + operation_over_aggregate_column(aggregate_column(column_name), operation, distinct).as(aggregate_alias), "#{group_field} AS #{group_alias}" ] diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 7ec4090..61fbf01 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -346,4 +346,13 @@ class CalculationsTest < ActiveRecord::TestCase def test_from_option_with_table_different_than_class assert_equal Account.count(:all), Company.count(:all, :from => 'accounts') end + + def test_distinct_is_honored_when_used_with_count_operation_after_group + # Count the number of authors for approved topics + approved_topics_count = Topic.group(:approved).count(:author_name)[true] + assert_equal approved_topics_count, 3 + # Count the number of distinct authors for approved Topics + distinct_authors_for_approved_count = Topic.group(:approved).count(:author_name, :distinct => true)[true] + assert_equal distinct_authors_for_approved_count, 2 + end end -- 1.7.0.4