Merge pull request #48817 from Shopify/return-false-early-if-non-AR-value-passed-in-include

Return `false` early when a non-AR object passed to `FinderMethods#include?`
This commit is contained in:
Jean Boussier 2023-07-27 08:29:47 +02:00 committed by GitHub
commit d53e67281a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 1 deletions

View File

@ -352,6 +352,10 @@ module ActiveRecord
# compared to the records in memory. If the relation is unloaded, an
# efficient existence query is performed, as in #exists?.
def include?(record)
# The existing implementation relies on receiving an Active Record instance as the input parameter named record.
# Any non-Active Record object passed to this implementation is guaranteed to return `false`.
return false unless record.is_a?(klass)
if loaded? || offset_value || limit_value || having_clause.any?
records.include?(record)
else
@ -360,7 +364,8 @@ module ActiveRecord
else
record.id
end
record.is_a?(klass) && exists?(id)
exists?(id)
end
end

View File

@ -411,6 +411,34 @@ class FinderTest < ActiveRecord::TestCase
end
end
def test_include_when_non_AR_object_passed_on_unloaded_relation
assert_no_queries do
assert_equal false, Customer.where(name: "David").include?("I'm not an AR object")
end
end
def test_include_when_non_AR_object_passed_on_loaded_relation
customers = Customer.where(name: "David").load
assert_no_queries do
assert_equal false, customers.include?("I'm not an AR object")
end
end
def test_member_when_non_AR_object_passed_on_unloaded_relation
assert_no_queries do
assert_equal false, Customer.where(name: "David").member?("I'm not an AR object")
end
end
def test_member_when_non_AR_object_passed_on_loaded_relation
customers = Customer.where(name: "David").load
assert_no_queries do
assert_equal false, customers.member?("I'm not an AR object")
end
end
def test_include_on_unloaded_relation_with_match
assert_sql(/1 AS one.*LIMIT/) do
assert_equal true, Customer.where(name: "David").include?(customers(:david))