From 4148c686ec2582c457adf277dec5b3ff496627c8 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 19 Jan 2010 15:50:47 +0530 Subject: [PATCH 1/2] Delegate :average, :minimum, :maximum, :sum to Relation --- .../lib/active_record/calculations.rb | 36 +-------------- .../relation/calculation_methods.rb | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index fc6cb793ab..db1f332336 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -64,41 +64,7 @@ module ActiveRecord 0 end - # Calculates the average value on a given column. The value is returned as - # a float, or +nil+ if there's no row. See +calculate+ for examples with - # options. - # - # Person.average('age') # => 35.8 - def average(column_name, options = {}) - calculate(:average, column_name, options) - end - - # Calculates the minimum value on a given column. The value is returned - # with the same data type of the column, or +nil+ if there's no row. See - # +calculate+ for examples with options. - # - # Person.minimum('age') # => 7 - def minimum(column_name, options = {}) - calculate(:minimum, column_name, options) - end - - # Calculates the maximum value on a given column. The value is returned - # with the same data type of the column, or +nil+ if there's no row. See - # +calculate+ for examples with options. - # - # Person.maximum('age') # => 93 - def maximum(column_name, options = {}) - calculate(:maximum, column_name, options) - end - - # Calculates the sum of values on a given column. The value is returned - # with the same data type of the column, 0 if there's no row. See - # +calculate+ for examples with options. - # - # Person.sum('age') # => 4562 - def sum(column_name, options = {}) - calculate(:sum, column_name, options) - end + delegate :average, :minimum, :maximum, :sum, :to => :scoped # This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts. # Options such as :conditions, :order, :group, :having, and :joins can be passed to customize the query. diff --git a/activerecord/lib/active_record/relation/calculation_methods.rb b/activerecord/lib/active_record/relation/calculation_methods.rb index 91de89e607..7dd6e04db9 100644 --- a/activerecord/lib/active_record/relation/calculation_methods.rb +++ b/activerecord/lib/active_record/relation/calculation_methods.rb @@ -5,20 +5,40 @@ module ActiveRecord calculate(:count, *construct_count_options_from_args(*args)) end - def average(column_name) - calculate(:average, column_name) + # Calculates the average value on a given column. The value is returned as + # a float, or +nil+ if there's no row. See +calculate+ for examples with + # options. + # + # Person.average('age') # => 35.8 + def average(column_name, options = {}) + calculation_relation(options).calculate(:average, column_name) end - def minimum(column_name) - calculate(:minimum, column_name) + # Calculates the minimum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. + # + # Person.minimum('age') # => 7 + def minimum(column_name, options = {}) + calculation_relation(options).calculate(:minimum, column_name) end - def maximum(column_name) - calculate(:maximum, column_name) + # Calculates the maximum value on a given column. The value is returned + # with the same data type of the column, or +nil+ if there's no row. See + # +calculate+ for examples with options. + # + # Person.maximum('age') # => 93 + def maximum(column_name, options = {}) + calculation_relation(options).calculate(:maximum, column_name) end - def sum(column_name) - calculate(:sum, column_name) + # Calculates the sum of values on a given column. The value is returned + # with the same data type of the column, 0 if there's no row. See + # +calculate+ for examples with options. + # + # Person.sum('age') # => 4562 + def sum(column_name, options = {}) + calculation_relation(options).calculate(:sum, column_name) end def calculate(operation, column_name, options = {}) @@ -49,6 +69,14 @@ module ActiveRecord 0 end + def calculation_relation(options = {}) + if options.present? + apply_finder_options(options.except(:distinct)).calculation_relation + else + (eager_loading? || includes_values.present?) ? construct_relation_for_association_calculations : self + end + end + private def execute_simple_calculation(operation, column_name, distinct) #:nodoc: From 9c7c7104f6a6074681f554c016f1b15a9ef8d267 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 19 Jan 2010 17:45:48 +0530 Subject: [PATCH 2/2] Fix the named scope equality check --- activerecord/lib/active_record/named_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 92030e5bfd..f1b8822892 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -182,7 +182,7 @@ module ActiveRecord end def ==(other) - to_a == other.to_a + other.respond_to?(:to_a) ? to_a == other.to_a : false end private