diff options
author | Joshua Peek <josh@joshpeek.com> | 2011-03-30 21:04:33 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2011-03-30 21:04:33 -0500 |
commit | 56a5da89dbcdd6d73f26f5c1be6221b684574b2b (patch) | |
tree | 577fbc16d37ed54bbda1a2a7477894caa6a7bfff /activerecord/lib/active_record/relation | |
parent | 5df076ad0965dc684afff8a019fd9f92a53ada76 (diff) | |
parent | 58c3ec1b7b7ee073edf9c245de5d06426be60a25 (diff) | |
download | rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.tar.gz rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.tar.bz2 rails-56a5da89dbcdd6d73f26f5c1be6221b684574b2b.zip |
Merge branch 'master' into sprockets
Conflicts:
railties/lib/rails/application/configuration.rb
Diffstat (limited to 'activerecord/lib/active_record/relation')
4 files changed, 50 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index bf5a60f458..d52b84179f 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -83,7 +83,7 @@ module ActiveRecord private def batch_order - "#{table_name}.#{primary_key} ASC" + "#{quoted_table_name}.#{quoted_primary_key} ASC" end end end 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 diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 426000fde1..8fa315bdf3 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -123,6 +123,12 @@ module ActiveRecord end end + # Same as +first+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # is found. Note that <tt>first!</tt> accepts no arguments. + def first! + first or raise RecordNotFound + end + # A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the # same arguments to this method as you can to <tt>find(:last)</tt>. def last(*args) @@ -137,6 +143,12 @@ module ActiveRecord end end + # Same as +last+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # is found. Note that <tt>last!</tt> accepts no arguments. + def last! + last or raise RecordNotFound + end + # A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the # same arguments to this method as you can to <tt>find(:all)</tt>. def all(*args) @@ -171,7 +183,9 @@ module ActiveRecord def exists?(id = nil) id = id.id if ActiveRecord::Base === id - relation = select("1").limit(1) + join_dependency = construct_join_dependency_for_association_find + relation = construct_relation_for_association_find(join_dependency) + relation = relation.except(:select).select("1").limit(1) case id when Array, Hash @@ -180,14 +194,13 @@ module ActiveRecord relation = relation.where(table[primary_key].eq(id)) if id end - relation.first ? true : false + connection.select_value(relation.to_sql) ? true : false end protected def find_with_associations - including = (@eager_load_values + @includes_values).uniq - join_dependency = ActiveRecord::Associations::JoinDependency.new(@klass, including, []) + join_dependency = construct_join_dependency_for_association_find relation = construct_relation_for_association_find(join_dependency) rows = connection.select_all(relation.to_sql, 'SQL', relation.bind_values) join_dependency.instantiate(rows) @@ -195,6 +208,11 @@ module ActiveRecord [] end + def construct_join_dependency_for_association_find + including = (@eager_load_values + @includes_values).uniq + ActiveRecord::Associations::JoinDependency.new(@klass, including, []) + end + def construct_relation_for_association_calculations including = (@eager_load_values + @includes_values).uniq join_dependency = ActiveRecord::Associations::JoinDependency.new(@klass, including, arel.froms.first) diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 9470e7c6c5..02b7056989 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -62,6 +62,10 @@ module ActiveRecord relation end + def reorder(*args) + except(:order).order(args) + end + def joins(*args) return self if args.compact.blank? |