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

This commit is contained in:
Pratik Naik
2010-01-03 03:27:14 +05:30
parent 6f5f23aaa7
commit eb7fdb9464
2 changed files with 32 additions and 14 deletions

View File

@@ -1579,17 +1579,8 @@ module ActiveRecord #:nodoc:
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 File

@@ -76,7 +76,7 @@ module ActiveRecord
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 @@ module ActiveRecord
: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 @@ module ActiveRecord
end
def reset
@first = @last = @create_scope = nil
@first = @last = @create_scope = @joined_tables = nil
@records = []
self
end
@@ -216,5 +216,32 @@ module ActiveRecord
@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