Я думаю, что вы ответили на свой вопрос, упомянув assert_queries
, но здесь говорится:
Я бы порекомендовал взглянуть на код, стоящий за assert_queries
, и использовать его для создания собственного метода, который вы можетеиспользовать для подсчета запросов.Главное волшебство, которое здесь задействовано, - это строка:
ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
Сегодня утром я немного повозился и вытащил части ActiveRecord, которые выполняют подсчет запросов, и придумал следующее:
module ActiveRecord
class QueryCounter
cattr_accessor :query_count do
0
end
IGNORED_SQL = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/]
def call(name, start, finish, message_id, values)
# FIXME: this seems bad. we should probably have a better way to indicate
# the query was cached
unless 'CACHE' == values[:name]
self.class.query_count += 1 unless IGNORED_SQL.any? { |r| values[:sql] =~ r }
end
end
end
end
ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)
module ActiveRecord
class Base
def self.count_queries(&block)
ActiveRecord::QueryCounter.query_count = 0
yield
ActiveRecord::QueryCounter.query_count
end
end
end
Вы сможете ссылаться на метод ActiveRecord::Base.count_queries
в любом месте.Передайте ему блок, в котором выполняются ваши запросы, и он вернет количество выполненных запросов:
ActiveRecord::Base.count_queries do
Ticket.first
end
Возвращает «1» для меня.Чтобы сделать это: поместите его в файл на lib/active_record/query_counter.rb
и укажите его в файле config/application.rb
, например:
require 'active_record/query_counter'
Привет!
Немногообъяснения, вероятно, требуется.Когда мы вызываем эту строку:
ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)
Мы подключаемся к небольшой структуре уведомлений Rails 3.Это блестящее небольшое дополнение к последней основной версии Rails, о котором никто не знает.Это позволяет нам подписываться на уведомления о событиях в Rails, используя метод subscribe
.Мы передаем событие, на которое хотим подписаться, в качестве первого аргумента, а затем любой объект, который отвечает на call
в качестве второго.
В этом случае, когда запрос выполняется, наш маленький счетчик запросов должным образом увеличивает ActiveRecordПеременная :: QueryCounter.query_count, но только для реальных запросов.
В любом случае, это было весело.Надеюсь, это пригодится вам.