如何使用 ActiveSupport::Notifications 订阅所有查询方法

How to subscribe to all query methods with ActiveSupport::Notifications

我不理解 ActiveSupport::Notifications 行为。我目前正在使用 ruby 2.5.0 和 rails 5.2,我正在尝试为 rspec (3.7.0) 创建一个自定义匹配器来验证查询是否已被触发或不是。目前我的匹配器看起来像这样:

RSpec::Matchers.define :trigger_query do
  supports_block_expectations

  match do |block|
    count_queries(&block).positive?
  end

  def count_queries &block
    count = 0

    counter_f = ->(_name, _started, _finished, _unique_id, payload) {
      count += 1 unless %w[CACHE SCHEMA].include?(payload[:name])
    }

    ActiveSupport::Notifications.subscribed(
      counter_f,
      "sql.active_record",
      &block
    )

    count
  end
end

但是当我尝试使用它时发生了意想不到的行为

# works
expect { Question.first(2) }.to trigger_query
# doesn't work
expect { Question.limit(2) }.to trigger_query

谁能告诉我我做错了什么?

limit 这样的查询方法将建立一个关系,但在调用者尝试从中获取数据之前不会对数据库进行查询。

一个简单的方法是将关系转换为数组:

Question.limit(2).to_a