diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-08 23:48:21 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-08 23:48:21 +0900 |
commit | 8cae8dcf5473a53179933eee1f0a36db436bbf1e (patch) | |
tree | c1dddeaaad52289f14cadce1e8b4c191e90ade48 | |
parent | e133573c8195f088ce29fbebabe3428cff9dc20d (diff) | |
parent | 07dcd99a5a5b0ccbaa91e0d18e3b7b165fecffb1 (diff) | |
download | rails-8cae8dcf5473a53179933eee1f0a36db436bbf1e.tar.gz rails-8cae8dcf5473a53179933eee1f0a36db436bbf1e.tar.bz2 rails-8cae8dcf5473a53179933eee1f0a36db436bbf1e.zip |
Merge pull request #35193 from kamipo/fix_exists_with_distinct_and_offset
Fix `relation.exists?` with giving both `distinct` and `offset`
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 12 | ||||
-rw-r--r-- | activerecord/test/cases/finder_test.rb | 10 |
2 files changed, 18 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 8f1065c1e7..91cfc4e849 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -307,8 +307,6 @@ module ActiveRecord return false if !conditions || limit_value == 0 - conditions = sanitize_forbidden_attributes(conditions) - if eager_loading? relation = apply_join_dependency(eager_loading: false) return relation.exists?(conditions) @@ -316,7 +314,7 @@ module ActiveRecord relation = construct_relation_for_exists(conditions) - skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false + skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false end # This method is called whenever no records are found with either a single @@ -354,7 +352,13 @@ module ActiveRecord end def construct_relation_for_exists(conditions) - relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1) + conditions = sanitize_forbidden_attributes(conditions) + + if distinct_value && offset_value + relation = limit(1) + else + relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1) + end case conditions when Array, Hash diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 6af2a43c7f..4040682280 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -271,6 +271,16 @@ class FinderTest < ActiveRecord::TestCase assert_equal true, Topic.exists?({}) end + def test_exists_with_distinct_and_offset_and_joins + assert Post.left_joins(:comments).distinct.offset(10).exists? + assert_not Post.left_joins(:comments).distinct.offset(11).exists? + end + + def test_exists_with_distinct_and_offset_and_select + assert Post.select(:body).distinct.offset(3).exists? + assert_not Post.select(:body).distinct.offset(4).exists? + end + # Ensure +exists?+ runs without an error by excluding distinct value. # See https://github.com/rails/rails/pull/26981. def test_exists_with_order_and_distinct |