diff options
Diffstat (limited to 'activerecord/lib/active_record/relation')
3 files changed, 32 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 6bf698fe97..c8adaddfca 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -208,14 +208,16 @@ module ActiveRecord end def execute_grouped_calculation(operation, column_name, distinct) #:nodoc: - group_attr = @group_values.first - association = @klass.reflect_on_association(group_attr.to_sym) - associated = association && association.macro == :belongs_to # only count belongs_to associations - group_field = associated ? association.primary_key_name : group_attr - group_alias = column_alias_for(group_field) - group_column = column_for(group_field) + group_attr = @group_values + association = @klass.reflect_on_association(group_attr.first.to_sym) + associated = group_attr.size == 1 && association && association.macro == :belongs_to # only count belongs_to associations + group_fields = Array(associated ? association.primary_key_name : group_attr) + group_aliases = group_fields.map { |field| column_alias_for(field) } + group_columns = group_aliases.zip(group_fields).map { |aliaz,field| + [aliaz, column_for(field)] + } - group = @klass.connection.adapter_name == 'FrontBase' ? group_alias : group_field + group = @klass.connection.adapter_name == 'FrontBase' ? group_aliases : group_fields if operation == 'count' && column_name == :all aggregate_alias = 'count_all' @@ -223,22 +225,33 @@ module ActiveRecord aggregate_alias = column_alias_for(operation, column_name) end - relation = except(:group).group(group) - relation.select_values = [ - operation_over_aggregate_column(aggregate_column(column_name), operation, distinct).as(aggregate_alias), - "#{group_field} AS #{group_alias}" + select_values = [ + operation_over_aggregate_column( + aggregate_column(column_name), + operation, + distinct).as(aggregate_alias) ] + select_values.concat group_fields.zip(group_aliases).map { |field,aliaz| + "#{field} AS #{aliaz}" + } + + relation = except(:group).group(group.join(',')) + relation.select_values = select_values + calculated_data = @klass.connection.select_all(relation.to_sql) if association - key_ids = calculated_data.collect { |row| row[group_alias] } + key_ids = calculated_data.collect { |row| row[group_aliases.first] } key_records = association.klass.base_class.find(key_ids) key_records = Hash[key_records.map { |r| [r.id, r] }] end ActiveSupport::OrderedHash[calculated_data.map do |row| - key = type_cast_calculated_value(row[group_alias], group_column) + key = group_columns.map { |aliaz, column| + type_cast_calculated_value(row[aliaz], column) + } + key = key.first if key.size == 1 key = key_records[key] if associated [key, type_cast_calculated_value(row[aggregate_alias], column_for(column_name), operation)] end] diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index e9e9c85122..4192456447 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -300,7 +300,7 @@ module ActiveRecord unless record conditions = arel.where_sql conditions = " [#{conditions}]" if conditions - raise RecordNotFound, "Couldn't find #{@klass.name} with ID=#{id}#{conditions}" + raise RecordNotFound, "Couldn't find #{@klass.name} with #{@klass.primary_key}=#{id}#{conditions}" end record diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index c5428dccd6..32c7d08daa 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -25,6 +25,11 @@ module ActiveRecord attribute.in(values) when Range, Arel::Relation attribute.in(value) + when ActiveRecord::Base + attribute.eq(value.quoted_id) + when Class + # FIXME: I think we need to deprecate this behavior + attribute.eq(value.name) else attribute.eq(value) end |