diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bff30f..789556a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## master +- add ability to ignore queries cached by the ORM with the new option `ignore_cached_queries` ([@gagalago][]) + ## 0.7.1 (2023-02-17) - Recognize private `#populate` and `#warmup` methods in Minitest classes. ([@palkan][]) diff --git a/README.md b/README.md index 0b47c01..aee9b5e 100644 --- a/README.md +++ b/README.md @@ -331,6 +331,10 @@ self.show_table_stats = true # Ignore matching queries NPlusOneControl.ignore = /^(BEGIN|COMMIT|SAVEPOINT|RELEASE)/ +# Ignore queries in cache +# https://guides.rubyonrails.org/configuring.html#configuring-query-cache +NPlusOneControl.ignore_cached_queries = false + # ActiveSupport notifications event to track queries. # We track ActiveRecord event by default, # but can also track rom-rb events ('sql.rom') as well. diff --git a/lib/n_plus_one_control.rb b/lib/n_plus_one_control.rb index 3ebc262..f4ca45f 100644 --- a/lib/n_plus_one_control.rb +++ b/lib/n_plus_one_control.rb @@ -19,7 +19,7 @@ module NPlusOneControl class << self attr_accessor :default_scale_factors, :verbose, :show_table_stats, :ignore, :event, - :backtrace_cleaner, :backtrace_length, :truncate_query_size + :backtrace_cleaner, :backtrace_length, :truncate_query_size, :ignore_cached_queries attr_reader :default_matching @@ -115,6 +115,9 @@ def truncate_query(sql) # Ignore matching queries self.ignore = /^(BEGIN|COMMIT|SAVEPOINT|RELEASE)/ + # Ignore queries cached + self.ignore_cached_queries = false + # ActiveSupport notifications event to track queries. # We track ActiveRecord event by default, # but can also track rom-rb events ('sql.rom') as well. diff --git a/lib/n_plus_one_control/executor.rb b/lib/n_plus_one_control/executor.rb index 5cb9e65..ae345db 100644 --- a/lib/n_plus_one_control/executor.rb +++ b/lib/n_plus_one_control/executor.rb @@ -22,6 +22,7 @@ def call def callback(_name, _start, _finish, _message_id, values) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/LineLength return if %w[CACHE SCHEMA].include? values[:name] return if values[:sql].match?(NPlusOneControl.ignore) + return if values[:cached] && NPlusOneControl.ignore_cached_queries return unless @pattern.nil? || (values[:sql] =~ @pattern) diff --git a/spec/n_plus_one_control/executor_spec.rb b/spec/n_plus_one_control/executor_spec.rb index e3f6e76..122fbbf 100644 --- a/spec/n_plus_one_control/executor_spec.rb +++ b/spec/n_plus_one_control/executor_spec.rb @@ -71,4 +71,32 @@ expect(result.last[1].size).to eq 3 end end + + context "with .ignore_cached_queries" do + let(:user) { create(:user) } + let(:populate) do + ->(n) { create_list(:post, n, user: user) } + end + + let(:observable) do + -> { User.cache { Post.find_each(&:user) } } + end + + around do |example| + old_ignore = NPlusOneControl.ignore_cached_queries + NPlusOneControl.ignore_cached_queries = true + example.call + NPlusOneControl.ignore_cached_queries = old_ignore + end + + it "ignore queries already executed that are now in cache" do + result = described_class.new(population: populate).call(&observable) + + expect(result.size).to eq 2 + expect(result.first[0]).to eq 2 + expect(result.first[1].size).to eq 2 + expect(result.last[0]).to eq 3 + expect(result.last[1].size).to eq 2 + end + end end