aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/calculations.rb
diff options
context:
space:
mode:
authorRyan Bigg <radarlistener@gmail.com>2011-04-05 21:22:38 +1000
committerRyan Bigg <radarlistener@gmail.com>2011-04-05 21:22:38 +1000
commit92e6255b58ce445d23580b669dac67d80e64d411 (patch)
treede3a01091787b30f1bafd462eedcb6210342493a /activerecord/lib/active_record/relation/calculations.rb
parent357578256fb55e32ae87c6fbf22a1c19f59ce264 (diff)
parentac07da8fc72b7a57fd4a60c0dcb5b777d85f9eb7 (diff)
downloadrails-92e6255b58ce445d23580b669dac67d80e64d411.tar.gz
rails-92e6255b58ce445d23580b669dac67d80e64d411.tar.bz2
rails-92e6255b58ce445d23580b669dac67d80e64d411.zip
Merge branch 'master' of github.com:lifo/docrails
* 'master' of github.com:lifo/docrails: (57 commits) Made the defaults section a little more readable and more to the point, giving a overview of the possibilities. Added information about default values added .'s to headings in the initialization textile page s/ERb/ERB/g (part II) s/ERb/ERB/g Bump up erubis to 2.7.0 Implicit actions named not_implemented can be rendered Gem::Specification#has_rdoc= is deprecated since rubygems 1.7.0 default_executable is deprecated since rubygems 1.7.0 Trivial fix to HTTP Digest auth MD5 example Moved Turn activation/dependency to railties fix typo Direct logging of Active Record to STDOUT so it's shown inline with the results in the console [DHH] Add using Turn with natural language test case names if the library is available (which it will be in Rails 3.1) [DHH] require turn only for minitest Use Turn to format all Rails tests and enable the natural language case names Improve docs. pass respond_with options to controller render when using a template for api navigation only try to display an api template in responders if the request is a get or there are no errors when using respond_with with an invalid resource and custom options, the default response status and error messages should be returned ...
Diffstat (limited to 'activerecord/lib/active_record/relation/calculations.rb')
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb35
1 files changed, 23 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index c1842b1a96..869eebfa34 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -196,24 +196,22 @@ module ActiveRecord
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_over_aggregate_column(column, operation, distinct)
- relation.select_values = [select_value]
+ if operation == "count" && (relation.limit_value || relation.offset_value)
+ # Shortcut when limit is zero.
+ return 0 if relation.limit_value == 0
- query_builder = relation.arel
+ query_builder = build_count_subquery(relation, column_name, distinct)
+ else
+ column = aggregate_column(column_name)
- if operation == "count"
- limit = relation.limit_value
- offset = relation.offset_value
+ select_value = operation_over_aggregate_column(column, operation, distinct)
- unless limit && offset
- query_builder.limit = nil
- query_builder.offset = nil
- end
+ relation.select_values = [select_value]
+
+ query_builder = relation.arel
end
type_cast_calculated_value(@klass.connection.select_value(query_builder.to_sql), column_for(column_name), operation)
@@ -312,5 +310,18 @@ module ActiveRecord
select if select !~ /(,|\*)/
end
end
+
+ def build_count_subquery(relation, column_name, distinct)
+ column_alias = Arel.sql('count_column')
+ subquery_alias = Arel.sql('subquery_for_count')
+
+ aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
+ relation.select_values = [aliased_column]
+ subquery = relation.arel.as(subquery_alias)
+
+ sm = Arel::SelectManager.new relation.engine
+ select_value = operation_over_aggregate_column(column_alias, 'count', distinct)
+ sm.project(select_value).from(subquery)
+ end
end
end