diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 3b693b5f17..bdfb0f45aa 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -688,9 +688,9 @@ module ActiveRecord #:nodoc: # Person.exists?(['name LIKE ?', "%#{query}%"]) # Person.exists? def exists?(id_or_conditions = {}) - construct_finder_arel({ - :conditions =>expand_id_conditions(id_or_conditions) - }).project(arel_table[primary_key]).take(1).count > 0 + connection.select_all(construct_finder_arel({ + :conditions => expand_id_conditions(id_or_conditions) + }).project(arel_table[primary_key]).take(1).to_sql).size > 0 end # Creates an object (or multiple objects) and saves it to the database, if validations pass. @@ -1688,9 +1688,9 @@ module ActiveRecord #:nodoc: scope = scope(:find) # TODO add lock to Arel - arel_table(options[:from] || table_name). - join(options[:merged_joins] || construct_join(options[:joins], scope)). - where(options[:merged_conditions] || construct_conditions(options[:conditions], scope)). + arel_table(table_name). + join(construct_join(options[:joins], scope)). + where(construct_conditions(options[:conditions], scope)). project(options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))). group(construct_group(options[:group], options[:having], scope)). order(construct_order(options[:order], scope)). @@ -1704,7 +1704,6 @@ module ActiveRecord #:nodoc: end def construct_join(joins, scope = :auto) - scope = scope(:find) if :auto == scope merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins]) case merged_joins when Symbol, Hash, Array @@ -1738,7 +1737,6 @@ module ActiveRecord #:nodoc: def construct_order(order, scope = :auto) sql = '' - scope = scope(:find) if :auto == scope scoped_order = scope[:order] if scope if order sql << order.to_s @@ -1752,19 +1750,16 @@ module ActiveRecord #:nodoc: end def construct_limit(options, scope = :auto) - scope = scope(:find) if :auto == scope options[:limit] ||= scope[:limit] if scope options[:limit] end def construct_offset(options, scope = :auto) - scope = scope(:find) if :auto == scope options[:offset] ||= scope[:offset] if scope options[:offset] end def construct_conditions(conditions, scope = :auto) - scope = scope(:find) if :auto == scope conditions = [conditions] conditions << scope[:conditions] if scope conditions << type_condition if finder_needs_type_condition? diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index 6bd2163dc2..c941be2837 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -153,9 +153,9 @@ module ActiveRecord conditions << construct_limited_ids_condition(conditions, options, join_dependency) if join_dependency && !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit]) if options[:group] - return execute_grouped_calculation(operation, column_name, options.merge(:merged_conditions => conditions, :merged_joins => joins, :distinct => distinct)) + return execute_grouped_calculation(operation, column_name, options.merge(:conditions => conditions, :joins => joins, :distinct => distinct)) else - return execute_simple_calculation(operation, column_name, options.merge(:merged_conditions => conditions, :merged_joins => joins, :distinct => distinct)) + return execute_simple_calculation(operation, column_name, options.merge(:conditions => conditions, :joins => joins, :distinct => distinct)) end end 0 @@ -163,15 +163,16 @@ module ActiveRecord def execute_simple_calculation(operation, column_name, options) #:nodoc: table = options[:from] || table_name + value = if operation == 'count' if column_name == :all && options[:select].blank? column_name = "*" elsif !options[:select].blank? column_name = options[:select] end - construct_finder_arel(options.merge(:select => Arel::Attribute.new(Arel(table), column_name).count(options[:distinct]))).select_value + construct_calculation_arel(options.merge(:select => Arel::Attribute.new(Arel(table), column_name).count(options[:distinct]))).select_value else - construct_finder_arel(options.merge(:select => Arel::Attribute.new(Arel(table), column_name).send(operation))).select_value + construct_calculation_arel(options.merge(:select => Arel::Attribute.new(Arel(table), column_name).send(operation))).select_value end type_cast_calculated_value(value, column_for(column_name), operation) @@ -196,7 +197,7 @@ module ActiveRecord options[:select] = "#{arel_column.as(aggregate_alias).to_sql}, #{group_field} AS #{group_alias}" end - calculated_data = connection.select_all(construct_finder_sql(options)) + calculated_data = connection.select_all(construct_calculation_arel(options).to_sql) if association key_ids = calculated_data.collect { |row| row[group_alias] } @@ -213,7 +214,22 @@ module ActiveRecord end end - protected + protected + + def construct_calculation_arel(options) + scope = scope(:find) + + arel_table(options[:from] || table_name). + join(options[:joins]). + where(options[:conditions]). + project(options[:select]). + group(construct_group(options[:group], options[:having], scope)). + order(options[:order].to_s). + take(construct_limit(options, scope)). + skip(construct_offset(options, scope) + ) + end + def construct_count_options_from_args(*args) options = {} column_name = :all diff --git a/arel b/arel index f44853a5aa..de843c8651 160000 --- a/arel +++ b/arel @@ -1 +1 @@ -Subproject commit f44853a5aa7f4481d99a3af4585f3a51272bc7f7 +Subproject commit de843c86518e4ac871d4bb5b0873bb6c184ac304