Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make Relation#includes behave exactly like the existing :include option

  • Loading branch information...
commit eb7fdb94647c42e31370b7faa1a474a966053f4d 1 parent 6f5f23a
@lifo lifo authored
View
13 activerecord/lib/active_record/base.rb
@@ -1579,17 +1579,8 @@ def construct_finder_arel(options = {}, scope = scope(:find))
order(construct_order(options[:order], scope)).
limit(construct_limit(options[:limit], scope)).
offset(construct_offset(options[:offset], scope)).
- from(options[:from])
-
- include_associations = merge_includes(scope && scope[:include], options[:include])
-
- if include_associations.any?
- if references_eager_loaded_tables?(options)
- relation = relation.eager_load(include_associations)
- else
- relation = relation.preload(include_associations)
- end
- end
+ from(options[:from]).
+ includes( merge_includes(scope && scope[:include], options[:include]))
lock = (scope && scope[:lock]) || options[:lock]
relation = relation.lock if lock.present?
View
33 activerecord/lib/active_record/relation.rb
@@ -76,7 +76,7 @@ def respond_to?(method, include_private = false)
def to_a
return @records if loaded?
- find_with_associations = @eager_load_associations.any?
+ find_with_associations = @eager_load_associations.any? || references_eager_loaded_tables?
@records = if find_with_associations
begin
@@ -90,7 +90,7 @@ def to_a
:offset => @relation.skipped,
:from => (@relation.send(:from_clauses) if @relation.send(:sources).present?)
},
- ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, @eager_load_associations, nil))
+ ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, @eager_load_associations + @include_associations, nil))
rescue ThrowResult
[]
end
@@ -157,7 +157,7 @@ def reload
end
def reset
- @first = @last = @create_scope = nil
+ @first = @last = @create_scope = @joined_tables = nil
@records = []
self
end
@@ -216,5 +216,32 @@ def where_clause(join_string = " AND ")
@relation.send(:where_clauses).join(join_string)
end
+ def references_eager_loaded_tables?
+ include_eager_order? || include_eager_conditions? || include_eager_select?
+ end
+
+ def include_eager_order?
+ order_clause = @relation.send(:order_clauses).join(', ')
+ (tables_in_string(order_clause) - joined_tables).any?
+ end
+
+ def include_eager_conditions?
+ (tables_in_string(where_clause) - joined_tables).any?
+ end
+
+ def include_eager_select?
+ select_clause = @relation.send(:select_clauses).join(', ')
+ (tables_in_string(select_clause) - joined_tables).any?
+ end
+
+ def joined_tables
+ @joined_tables ||= (tables_in_string(@relation.joins(relation)) + [table.name, table.table_alias]).compact.uniq
+ end
+
+ def tables_in_string(string)
+ return [] if string.blank?
+ string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.uniq
+ end
+
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.