diff options
author | Yves Senn <yves.senn@gmail.com> | 2014-02-28 09:49:52 +0100 |
---|---|---|
committer | Yves Senn <yves.senn@gmail.com> | 2014-02-28 09:56:07 +0100 |
commit | d1e7cd14c29f1ef45f2f36e79cd99eb580036991 (patch) | |
tree | be4a5428a28c5a9a0c92a5108f9b0c6adee14bfb /activerecord | |
parent | 544c78a4e964b1971c2409f4dc805f2d4161990e (diff) | |
download | rails-d1e7cd14c29f1ef45f2f36e79cd99eb580036991.tar.gz rails-d1e7cd14c29f1ef45f2f36e79cd99eb580036991.tar.bz2 rails-d1e7cd14c29f1ef45f2f36e79cd99eb580036991.zip |
`includes` uses SQL parsing when String joins are involved.
This is a partial revert of 22b3481ba2aa55fad1f9a5db94072312b345fb55.
The current implementation of `references_eager_loaded_tables?` needs to know
every table involved in the query. With the current API this is not possible
without SQL parsing.
While a2dab46cae35a06fd5c5500037177492a047c252 deprecated SQL parsing for `includes`.
It did not issue deprecation warnings when String joins are involved. This resulted
in a breaking change after the deprecated behavior was removed (22b3481ba2aa55fad1f9a5db94072312b345fb55).
We will need to rethink the usage of `includes`, `preload` and `eager_load` but for now,
this brings back the old *working* behavior.
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 11 | ||||
-rw-r--r-- | activerecord/test/cases/associations/eager_test.rb | 9 |
3 files changed, 26 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 2845e945db..654026da4c 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,10 @@ +* `includes` is able to detect the right preloading strategy when string + joins are involved. + + Fixes #14109. + + *Aaron Patterson*, *Yves Senn* + * Fixed error with validation with enum fields for records where the value for any enum attribute is always evaluated as 0 during uniqueness validation. diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index fb213dc6f7..9eaba4a655 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -617,7 +617,9 @@ module ActiveRecord def references_eager_loaded_tables? joined_tables = arel.join_sources.map do |join| - unless join.is_a?(Arel::Nodes::StringJoin) + if join.is_a?(Arel::Nodes::StringJoin) + tables_in_string(join.left) + else [join.left.table_name, join.left.table_alias] end end @@ -629,5 +631,12 @@ module ActiveRecord (references_values - joined_tables).any? end + + def tables_in_string(string) + return [] if string.blank? + # always convert table names to downcase as in Oracle quoted table names are in uppercase + # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries + string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_'] + end end end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 498a4e8144..5522a33b79 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1194,4 +1194,13 @@ class EagerAssociationTest < ActiveRecord::TestCase authors(:david).essays.includes(:writer).any? end end + + test "preloading associations with string joins and order references" do + author = assert_queries(2) { + Author.includes(:posts).joins("LEFT JOIN posts ON posts.author_id = authors.id").order("posts.title DESC").first + } + assert_no_queries { + assert_equal 5, author.posts.size + } + end end |