diff options
Diffstat (limited to 'activerecord/lib/active_record/relation/calculations.rb')
-rw-r--r-- | activerecord/lib/active_record/relation/calculations.rb | 70 |
1 files changed, 21 insertions, 49 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 7239270c4d..27c04b0952 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -56,15 +56,7 @@ module ActiveRecord # # Person.sum(:age) # => 4562 def sum(*args) - if block_given? - ActiveSupport::Deprecation.warn( - "Calling #sum with a block is deprecated and will be removed in Rails 4.1. " \ - "If you want to perform sum calculation over the array of elements, use `to_a.sum(&block)`." - ) - self.to_a.sum(*args) {|*block_args| yield(*block_args)} - else - calculate(:sum, *args) - end + calculate(:sum, *args) end # This calculates aggregate values in the given column. Methods for count, sum, average, @@ -99,23 +91,15 @@ module ActiveRecord # # Person.sum("2 * age") def calculate(operation, column_name, options = {}) - relation = with_default_scope - - if column_name.is_a?(Symbol) && attribute_aliases.key?(column_name.to_s) - column_name = attribute_aliases[column_name.to_s].to_sym + if column_name.is_a?(Symbol) && attribute_alias?(column_name) + column_name = attribute_alias(column_name) end - if relation.equal?(self) - if has_include?(column_name) - construct_relation_for_association_calculations.calculate(operation, column_name, options) - else - perform_calculation(operation, column_name, options) - end + if has_include?(column_name) + construct_relation_for_association_calculations.calculate(operation, column_name, options) else - relation.calculate(operation, column_name, options) + perform_calculation(operation, column_name, options) end - rescue ThrowResult - 0 end # Use <tt>pluck</tt> as a shortcut to select one or more attributes without @@ -153,39 +137,31 @@ module ActiveRecord # def pluck(*column_names) column_names.map! do |column_name| - if column_name.is_a?(Symbol) - if attribute_aliases.key?(column_name.to_s) - column_name = attribute_aliases[column_name.to_s].to_sym - end - - if self.columns_hash.key?(column_name.to_s) - column_name = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}" - end + if column_name.is_a?(Symbol) && attribute_alias?(column_name) + attribute_alias(column_name) + else + column_name.to_s end - - column_name end if has_include?(column_names.first) construct_relation_for_association_calculations.pluck(*column_names) else relation = spawn - relation.select_values = column_names + relation.select_values = column_names.map { |cn| + columns_hash.key?(cn) ? arel_table[cn] : cn + } result = klass.connection.select_all(relation.arel, nil, bind_values) columns = result.columns.map do |key| klass.column_types.fetch(key) { - result.column_types.fetch(key) { - Class.new { def type_cast(v); v; end }.new - } + result.column_types.fetch(key) { result.identity_type } } end result = result.map do |attributes| values = klass.initialize_attributes(attributes).values - columns.zip(values).map do |column, value| - column.type_cast(value) - end + columns.zip(values).map { |column, value| column.type_cast value } end columns.one? ? result.map!(&:first) : result end @@ -210,22 +186,16 @@ module ActiveRecord # If #count is used with #distinct / #uniq it is considered distinct. (eg. relation.distinct.count) distinct = self.distinct_value - if options.has_key?(:distinct) - ActiveSupport::Deprecation.warn "The :distinct option for `Relation#count` is deprecated. " \ - "Please use `Relation#distinct` instead. (eg. `relation.distinct.count`)" - distinct = options[:distinct] - end if operation == "count" - column_name ||= (select_for_count || :all) + column_name ||= select_for_count unless arel.ast.grep(Arel::Nodes::OuterJoin).empty? distinct = true end column_name = primary_key if column_name == :all && distinct - - distinct = nil if column_name =~ /\s*DISTINCT\s+/i + distinct = nil if column_name =~ /\s*DISTINCT[\s(]+/i end if group_values.any? @@ -386,10 +356,12 @@ module ActiveRecord column ? column.type_cast(value) : value end + # TODO: refactor to allow non-string `select_values` (eg. Arel nodes). def select_for_count if select_values.present? - select = select_values.join(", ") - select if select !~ /[,*]/ + select_values.join(", ") + else + :all end end |