diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 1dc465b444309..cf697e7515387 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -29,7 +29,7 @@ def #{method_name}(...) end class Store # :nodoc: - attr_reader :enabled + attr_accessor :enabled alias_method :enabled?, :enabled def initialize(max_size) @@ -38,11 +38,6 @@ def initialize(max_size) @enabled = false end - def enabled=(enabled) - clear if @enabled && !enabled - @enabled = enabled - end - def size @map.size end diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb index 18b0a7c901f53..3376d888d3b46 100644 --- a/activerecord/lib/active_record/query_cache.rb +++ b/activerecord/lib/active_record/query_cache.rb @@ -8,7 +8,13 @@ module ClassMethods # If it's not, it will execute the given block. def cache(&block) if connected? || !configurations.empty? - connection_pool.enable_query_cache(&block) + pool = connection_pool + was_enabled = pool.query_cache_enabled + begin + pool.enable_query_cache(&block) + ensure + pool.clear_query_cache unless was_enabled + end else yield end @@ -30,7 +36,10 @@ def self.run end def self.complete(pools) - pools.each(&:disable_query_cache!) + pools.each do |pool| + pool.disable_query_cache! + pool.clear_query_cache + end ActiveRecord::Base.connection_handler.each_connection_pool do |pool| pool.release_connection if pool.active_connection? && !pool.connection.transaction_open? diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index 333b2f1ea02fb..a90b5147f10a3 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -91,6 +91,24 @@ def test_writes_should_always_clear_cache assert_cache :off end + def test_reads_dont_clear_disabled_cache + assert_cache :off + + mw = middleware { |env| + Post.first + query_cache = ActiveRecord::Base.connection.query_cache + assert_equal 1, query_cache.size, query_cache.inspect + Post.connection.uncached do + Post.count # shouldn't clear the cache + end + query_cache = ActiveRecord::Base.connection.query_cache + assert_equal 1, query_cache.size, query_cache.inspect + } + mw.call({}) + + assert_cache :off + end + def test_exceptional_middleware_clears_and_disables_cache_on_error assert_cache :off @@ -808,7 +826,7 @@ def test_cache_gets_cleared_after_migration end def test_find - assert_called(Task.connection.query_cache, :clear, times: 2) do + assert_called(Task.connection.query_cache, :clear, times: 1) do assert_not Task.connection.query_cache_enabled Task.cache do assert Task.connection.query_cache_enabled