Skip to content

Commit 3ceeeb8

Browse files
committed
Fix find_by cache to work with multiple contexts
Previously it was global across contexts which would cause issues if contexts don't generate the same queries.
1 parent 39c7186 commit 3ceeeb8

3 files changed

Lines changed: 13 additions & 4 deletions

File tree

activerecord/lib/active_record/core.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
263263

264264
module ClassMethods
265265
def initialize_find_by_cache # :nodoc:
266-
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
266+
model_schemas.each_value(&:initialize_find_by_cache)
267267
end
268268

269269
def find(*ids) # :nodoc:
@@ -402,8 +402,7 @@ def type_caster # :nodoc:
402402
end
403403

404404
def cached_find_by_statement(connection, key, &block) # :nodoc:
405-
cache = @find_by_statement_cache[connection.prepared_statements]
406-
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
405+
model_schema.cached_find_by_statement(connection, key, &block)
407406
end
408407

409408
private

activerecord/lib/active_record/model_schema/schema.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ def table_name=(value)
196196
@sequence_name = nil
197197
end
198198

199+
def cached_find_by_statement(connection, key, &block)
200+
@find_by_statement_cache ||= { true => Concurrent::Map.new, false => Concurrent::Map.new }
201+
cache = @find_by_statement_cache[connection.prepared_statements]
202+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
203+
end
204+
205+
def initialize_find_by_cache
206+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
207+
end
208+
199209
# Load schema information from the schema cache
200210
def load_schema
201211
return if schema_loaded?

activerecord/test/cases/core_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def attribute_for_inspect(attr_name)
246246
def test_find_by_cache_does_not_duplicate_entries
247247
Topic.initialize_find_by_cache
248248
using_prepared_statements = Topic.lease_connection.prepared_statements
249-
topic_find_by_cache = Topic.instance_variable_get("@find_by_statement_cache")[using_prepared_statements]
249+
topic_find_by_cache = Topic.model_schema.instance_variable_get("@find_by_statement_cache")[using_prepared_statements]
250250

251251
assert_difference -> { topic_find_by_cache.size }, +1 do
252252
Topic.find(1)

0 commit comments

Comments
 (0)