<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,7 @@
 *Edge*
 
+* Add :from option to calculations.  #397 [Ben Munat]
+
 * Add :validate option to associations to enable/disable the automatic validation of associated models. Resolves #301. [Jan De Poorter]
 
 * PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later.  [Jeremy Kemper]</diff>
      <filename>activerecord/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 module ActiveRecord
   module Calculations #:nodoc:
-    CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include]
+    CALCULATIONS_OPTIONS = [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include, :from]
     def self.included(base)
       base.extend(ClassMethods)
     end
@@ -27,6 +27,8 @@ module ActiveRecord
       # * &lt;tt&gt;:select&lt;/tt&gt;: By default, this is * as in SELECT * FROM, but can be changed if you, for example, want to do a join but not
       #   include the joined columns.
       # * &lt;tt&gt;:distinct&lt;/tt&gt;: Set this to true to make this a distinct calculation, such as SELECT COUNT(DISTINCT posts.id) ...
+      # * &lt;tt&gt;:from&lt;/tt&gt; - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
+      #   of a database view).
       #
       # Examples for counting all:
       #   Person.count         # returns the total count of all people
@@ -178,8 +180,12 @@ module ActiveRecord
           sql = &quot;SELECT COUNT(*) AS #{aggregate_alias}&quot; if use_workaround
 
           sql &lt;&lt; &quot;, #{options[:group_field]} AS #{options[:group_alias]}&quot; if options[:group]
-          sql &lt;&lt; &quot; FROM (SELECT #{distinct}#{column_name}&quot; if use_workaround
-          sql &lt;&lt; &quot; FROM #{connection.quote_table_name(table_name)} &quot;
+          if options[:from]
+            sql &lt;&lt; &quot; FROM #{options[:from]} &quot;
+          else
+            sql &lt;&lt; &quot; FROM (SELECT #{distinct}#{column_name}&quot; if use_workaround
+            sql &lt;&lt; &quot; FROM #{connection.quote_table_name(table_name)} &quot;
+          end
           if merged_includes.any?
             join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, options[:joins])
             sql &lt;&lt; join_dependency.join_associations.collect{|join| join.association_join }.join</diff>
      <filename>activerecord/lib/active_record/calculations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,7 @@
 require &quot;cases/helper&quot;
 require 'models/company'
 require 'models/topic'
+require 'models/edge'
 
 Company.has_many :accounts
 
@@ -274,4 +275,49 @@ class CalculationsTest &lt; ActiveRecord::TestCase
   def test_should_sum_expression
     assert_equal 636, Account.sum(&quot;2 * credit_limit&quot;)
   end
+
+  def test_count_with_from_option
+    assert_equal Company.count(:all), Company.count(:all, :from =&gt; 'companies')
+    assert_equal Account.count(:all, :conditions =&gt; &quot;credit_limit = 50&quot;),
+        Account.count(:all, :from =&gt; 'accounts', :conditions =&gt; &quot;credit_limit = 50&quot;)
+    assert_equal Company.count(:type, :conditions =&gt; {:type =&gt; &quot;Firm&quot;}),
+        Company.count(:type, :conditions =&gt; {:type =&gt; &quot;Firm&quot;}, :from =&gt; 'companies')
+  end
+
+  def test_sum_with_from_option
+    assert_equal Account.sum(:credit_limit), Account.sum(:credit_limit, :from =&gt; 'accounts')
+    assert_equal Account.sum(:credit_limit, :conditions =&gt; &quot;credit_limit &gt; 50&quot;),
+        Account.sum(:credit_limit, :from =&gt; 'accounts', :conditions =&gt; &quot;credit_limit &gt; 50&quot;)
+  end
+
+  def test_average_with_from_option
+    assert_equal Account.average(:credit_limit), Account.average(:credit_limit, :from =&gt; 'accounts')
+    assert_equal Account.average(:credit_limit, :conditions =&gt; &quot;credit_limit &gt; 50&quot;),
+        Account.average(:credit_limit, :from =&gt; 'accounts', :conditions =&gt; &quot;credit_limit &gt; 50&quot;)
+  end
+
+  def test_minimum_with_from_option
+    assert_equal Account.minimum(:credit_limit), Account.minimum(:credit_limit, :from =&gt; 'accounts')
+    assert_equal Account.minimum(:credit_limit, :conditions =&gt; &quot;credit_limit &gt; 50&quot;),
+        Account.minimum(:credit_limit, :from =&gt; 'accounts', :conditions =&gt; &quot;credit_limit &gt; 50&quot;)
+  end
+
+  def test_maximum_with_from_option
+    assert_equal Account.maximum(:credit_limit), Account.maximum(:credit_limit, :from =&gt; 'accounts')
+    assert_equal Account.maximum(:credit_limit, :conditions =&gt; &quot;credit_limit &gt; 50&quot;),
+        Account.maximum(:credit_limit, :from =&gt; 'accounts', :conditions =&gt; &quot;credit_limit &gt; 50&quot;)
+  end
+
+  def test_from_option_with_specified_index
+    if Edge.connection.adapter_name == 'MySQL'
+      assert_equal Edge.count(:all), Edge.count(:all, :from =&gt; 'edges USE INDEX(unique_edge_index)')
+      assert_equal Edge.count(:all, :conditions =&gt; 'sink_id &lt; 5'),
+          Edge.count(:all, :from =&gt; 'edges USE INDEX(unique_edge_index)', :conditions =&gt; 'sink_id &lt; 5')
+    end
+  end
+
+  def test_from_option_with_table_different_than_class
+    assert_equal Account.count(:all), Company.count(:all, :from =&gt; 'accounts')
+  end
+
 end</diff>
      <filename>activerecord/test/cases/calculations_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e170d34a634c93efef471f9c0c1dac7377f1fc40</id>
    </parent>
  </parents>
  <author>
    <name>Ben Munat</name>
    <email>bmunat@gmail.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/ddab9d7fdf49eb064f3f669bbf6ebb41e75e9fb5</url>
  <id>ddab9d7fdf49eb064f3f669bbf6ebb41e75e9fb5</id>
  <committed-date>2008-06-11T18:07:57-07:00</committed-date>
  <authored-date>2008-06-11T16:26:35-07:00</authored-date>
  <message>Add :from option to calculations.  [#397 state:resolved]</message>
  <tree>9fd10026edaf41bb723f8fa06c3ee0c880d2c212</tree>
  <committer>
    <name>Jeremy Kemper</name>
    <email>jeremy@bitsweat.net</email>
  </committer>
</commit>
