From c9ab7098be7bdd748c0f4a49c8ef015b4aad3108 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 18 Dec 2008 19:07:55 +0000 Subject: Ensure :include checks joins when determining if it can preload [#528 state:resolved] --- activerecord/lib/active_record/associations.rb | 43 ++++++++++++++++++++------ 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 3fbbea43ed..bc2a88ef7e 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1731,6 +1731,11 @@ module ActiveRecord return sanitize_sql(sql) end + def tables_in_string(string) + return [] if string.blank? + string.scan(/([\.a-zA-Z_]+).?\./).flatten + end + def conditions_tables(options) # look in both sets of conditions conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| @@ -1741,37 +1746,55 @@ module ActiveRecord else all << cond end end - conditions.join(' ').scan(/([\.a-zA-Z_]+).?\./).flatten + tables_in_string(conditions.join(' ')) end def order_tables(options) order = [options[:order], scope(:find, :order) ].join(", ") return [] unless order && order.is_a?(String) - order.scan(/([\.a-zA-Z_]+).?\./).flatten + tables_in_string(order) end def selects_tables(options) select = options[:select] return [] unless select && select.is_a?(String) - select.scan(/"?([\.a-zA-Z_]+)"?.?\./).flatten + tables_in_string(select) + end + + def joined_tables(options) + scope = scope(:find) + joins = options[:joins] + merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins]) + [table_name] + case merged_joins + when Symbol, Hash, Array + if array_of_strings?(merged_joins) + tables_in_string(merged_joins.join(' ')) + else + join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil) + [table_name] + join_dependency.join_associations.collect {|join_association| [join_association.aliased_join_table_name, join_association.aliased_table_name]}.flatten.compact + end + else + tables_in_string(merged_joins) + end end # Checks if the conditions reference a table other than the current model table - def include_eager_conditions?(options, tables = nil) - ((tables || conditions_tables(options)) - [table_name]).any? + def include_eager_conditions?(options, tables = nil, joined_tables = nil) + ((tables || conditions_tables(options)) - (joined_tables || joined_tables(options))).any? end # Checks if the query order references a table other than the current model's table. - def include_eager_order?(options, tables = nil) - ((tables || order_tables(options)) - [table_name]).any? + def include_eager_order?(options, tables = nil, joined_tables = nil) + ((tables || order_tables(options)) - (joined_tables || joined_tables(options))).any? end - def include_eager_select?(options) - (selects_tables(options) - [table_name]).any? + def include_eager_select?(options, joined_tables = nil) + (selects_tables(options) - (joined_tables || joined_tables(options))).any? end def references_eager_loaded_tables?(options) - include_eager_order?(options) || include_eager_conditions?(options) || include_eager_select?(options) + joined_tables = joined_tables(options) + include_eager_order?(options, nil, joined_tables) || include_eager_conditions?(options, nil, joined_tables) || include_eager_select?(options, joined_tables) end def using_limitable_reflections?(reflections) -- cgit v1.2.3