如何使用 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