Myślę, że odpowiedziałeś na własne pytanie, wspominając assert_queries
, ale oto idzie:
Polecam przyjrzeć się kodowi za assert_queries
i używając tego do zbudowania własnej metody, której możesz użyć do zliczania zapytań. Główną magią w tym przypadku jest ta linia:
ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
Dziś rano trochę majstrowałem i wyrwałem części ActiveRecord, które zliczają zapytania, i wymyśliłem to:
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
Będziesz mógł odwołać się do ActiveRecord::Base.count_queries
metoda w dowolnym miejscu. Przekaż mu blok, w którym są uruchamiane twoje zapytania, a zwróci liczbę zapytań, które zostały wykonane:
ActiveRecord::Base.count_queries do
Ticket.first
end
Zwraca mi „1”. Aby to zadziałało:umieść go w pliku w lib/active_record/query_counter.rb
i wymagaj go w swoim config/application.rb
plik w ten sposób:
require 'active_record/query_counter'
Hej, presto!
Wymagane jest prawdopodobnie trochę wyjaśnienia. Kiedy dzwonimy do tej linii:
ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)
Podłączamy się do małego frameworka powiadomień Rails 3. Jest to lśniący, mały dodatek do najnowszej głównej wersji Rails, o którym nikt tak naprawdę nie wie. Pozwala nam subskrybować powiadomienia o zdarzeniach w Railsach za pomocą subscribe
metoda. W przypadku, gdy chcemy się zasubskrybować, przekazujemy jako pierwszy argument każdy obiekt, który odpowiada na call
jako drugi.
W tym przypadku, gdy zapytanie zostanie wykonane, nasz mały licznik zapytań sumiennie zwiększy zmienną ActiveRecord::QueryCounter.query_count, ale tylko dla rzeczywistej zapytania.
W każdym razie było fajnie. Mam nadzieję, że ci się przyda.