diff options
author | Jon Leighton <j@jonathanleighton.com> | 2012-01-16 21:14:34 +0000 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2012-01-16 21:32:12 +0000 |
commit | a2dab46cae35a06fd5c5500037177492a047c252 (patch) | |
tree | af4be28070368eccdc1151df59384c9ca7aee1bf /activerecord/lib/active_record | |
parent | 46ea4442f3abc33d15e03487bae1c80346eab49a (diff) | |
download | rails-a2dab46cae35a06fd5c5500037177492a047c252.tar.gz rails-a2dab46cae35a06fd5c5500037177492a047c252.tar.bz2 rails-a2dab46cae35a06fd5c5500037177492a047c252.zip |
Deprecate inferred JOINs with includes + SQL snippets.
See the CHANGELOG for details.
Fixes #950.
Diffstat (limited to 'activerecord/lib/active_record')
4 files changed, 29 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index 3759af26d6..0209ce36df 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -20,7 +20,7 @@ module ActiveRecord # It's okay to just apply all these like this. The options will only be present if the # association supports that option; this is enforced by the association builder. scope = scope.apply_finder_options(options.slice( - :readonly, :include, :order, :limit, :joins, :group, :having, :offset, :select)) + :readonly, :include, :references, :order, :limit, :joins, :group, :having, :offset, :select)) if options[:through] && !options[:include] scope = scope.includes(source_options[:include]) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index d4f59100e8..6e2e5f9de0 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -1,7 +1,7 @@ module ActiveRecord::Associations::Builder class Association #:nodoc: class_attribute :valid_options - self.valid_options = [:class_name, :foreign_key, :select, :conditions, :include, :extend, :readonly, :validate] + self.valid_options = [:class_name, :foreign_key, :select, :conditions, :include, :extend, :readonly, :validate, :references] # Set by subclasses class_attribute :macro diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 7838271e5c..01019db2cc 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- require 'active_support/core_ext/object/blank' +require 'active_support/deprecation' module ActiveRecord # = Active Record Relation @@ -520,9 +521,30 @@ module ActiveRecord # always convert table names to downcase as in Oracle quoted table names are in uppercase joined_tables = joined_tables.flatten.compact.map { |t| t.downcase }.uniq - - (tables_in_string(to_sql) - joined_tables).any? || - (references_values - joined_tables).any? + string_tables = tables_in_string(to_sql) + + if (references_values - joined_tables).any? + true + elsif (string_tables - joined_tables).any? + ActiveSupport::Deprecation.warn( + "It looks like you are eager loading table(s) (one of: #{string_tables.join(', ')}) " \ + "that are referenced in a string SQL snippet. For example: \n" \ + "\n" \ + " Post.includes(:comments).where(\"comments.title = 'foo'\")\n" \ + "\n" \ + "Currently, Active Record recognises the table in the string, and knows to JOIN the " \ + "comments table to the query, rather than loading comments in a separate query. " \ + "However, doing this without writing a full-blown SQL parser is inherently flawed. " \ + "Since we don't want to write an SQL parser, we are removing this functionality. " \ + "From now on, you must explicitly tell Active Record when you are referencing a table " \ + "from a string:\n" \ + "\n" \ + " Post.includes(:comments).where(\"comments.title = 'foo'\").references(:comments)\n\n" + ) + true + else + false + end end def tables_in_string(string) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index c25570d758..7131aa29b6 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -122,7 +122,7 @@ module ActiveRecord result end - VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend, + VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend, :references, :order, :select, :readonly, :group, :having, :from, :lock ] def apply_finder_options(options) @@ -133,7 +133,7 @@ module ActiveRecord finders = options.dup finders.delete_if { |key, value| value.nil? && key != :limit } - ([:joins, :select, :group, :order, :having, :limit, :offset, :from, :lock, :readonly] & finders.keys).each do |finder| + ((VALID_FIND_OPTIONS - [:conditions, :include, :extend]) & finders.keys).each do |finder| relation = relation.send(finder, finders[finder]) end |