From 4148c686ec2582c457adf277dec5b3ff496627c8 Mon Sep 17 00:00:00 2001
From: Pratik Naik <pratiknaik@gmail.com>
Date: Tue, 19 Jan 2010 15:50:47 +0530
Subject: Delegate :average, :minimum, :maximum, :sum to Relation

---
 activerecord/lib/active_record/calculations.rb     | 36 +-----------------
 .../active_record/relation/calculation_methods.rb  | 44 ++++++++++++++++++----
 2 files changed, 37 insertions(+), 43 deletions(-)

(limited to 'activerecord/lib')

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 <tt>:conditions</tt>, <tt>:order</tt>, <tt>:group</tt>, <tt>:having</tt>, and <tt>:joins</tt> 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:
-- 
cgit v1.2.3