Skip to content

Commit c9075e3

Browse files
authored
Merge pull request rails#51987 from fatkodima/exists-and-loaded2
Optimize `ActiveRecord::Relation#exists?` with no conditions for loaded relations
2 parents a14eb2d + 9e85d04 commit c9075e3

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

activerecord/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
* Optimize `Relation#exists?` when records are loaded and the relation has no conditions.
2+
3+
This can avoid queries in some cases.
4+
5+
*fatkodima*
6+
17
* Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
28
by these values.
39

activerecord/lib/active_record/relation/finder_methods.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ def exists?(conditions = :none)
365365
end
366366

367367
return false if !conditions || limit_value == 0
368+
return records.any?(&:persisted?) if conditions == :none && loaded?
368369

369370
if eager_loading?
370371
relation = apply_join_dependency(eager_loading: false)

activerecord/test/cases/finder_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,30 @@ def test_exists_returns_false_with_false_arg
289289
assert_equal false, Topic.exists?(false)
290290
end
291291

292+
def test_exists_with_loaded_relation
293+
topics = Topic.all.load
294+
assert_no_queries do
295+
assert_predicate topics, :exists?
296+
end
297+
end
298+
299+
def test_exists_with_empty_loaded_relation
300+
Topic.delete_all
301+
topics = Topic.all.load
302+
assert_no_queries do
303+
assert_not_predicate topics, :exists?
304+
end
305+
end
306+
307+
def test_exists_with_loaded_relation_having_unsaved_records
308+
author = authors(:david)
309+
posts = author.posts.load
310+
assert_not_empty posts
311+
posts.each(&:destroy)
312+
313+
assert_not_predicate posts, :exists?
314+
end
315+
292316
# exists? should handle nil for id's that come from URLs and always return false
293317
# (example: Topic.exists?(params[:id])) where params[:id] is nil
294318
def test_exists_with_nil_arg

0 commit comments

Comments
 (0)