From 949f3987ad337fb23d411310d39b5c43bee854e5 Mon Sep 17 00:00:00 2001 From: stopdropandrew Date: Wed, 5 Nov 2008 13:49:17 -0800 Subject: [PATCH] Count calculations respect explicit selects specified in scopes. --- activerecord/lib/active_record/calculations.rb | 20 ++++++++++++++------ activerecord/test/cases/calculations_test.rb | 13 ++++++++++++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index 5e33cf1..18b2bf1 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -132,23 +132,31 @@ module ActiveRecord protected def construct_count_options_from_args(*args) options = {} - column_name = :all - + column_name = nil + # We need to handle # count() # count(:column_name=:all) # count(options={}) # count(column_name=:all, options={}) + # selects specified by scopes case args.size + when 0 + column_name = (scope(:find) || {})[:select] when 1 - args[0].is_a?(Hash) ? options = args[0] : column_name = args[0] + if args[0].is_a?(Hash) + column_name = (scope(:find) || {})[:select] + options = args[0] + else + column_name = args[0] + end when 2 column_name, options = args else raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}" - end if args.size > 0 - - [column_name, options] + end + + [column_name || :all, options] end def construct_calculation_sql(operation, column_name, options) #:nodoc: diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 0fa6150..d2740c1 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -251,7 +251,18 @@ class CalculationsTest < ActiveRecord::TestCase assert_equal 6, Account.count(:distinct => true, :include => :firm) assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit) end - + + def test_should_count_scoped_select + Account.update_all("credit_limit = 50") + assert_equal 1, Account.scoped(:select => "DISTINCT credit_limit").count + end + + def test_should_count_scoped_select_with_options + Account.update_all("credit_limit = 50") + Account.first.update_attribute('credit_limit', 49) + assert_equal 1, Account.scoped(:select => "DISTINCT credit_limit").count(:conditions => [ 'credit_limit >= 50'] ) + end + def test_should_count_manual_select_with_include assert_equal 6, Account.count(:select => "DISTINCT accounts.id", :include => :firm) end -- 1.5.5