Tôi nghĩ rằng bạn đã trả lời câu hỏi của chính mình bằng cách đề cập đến assert_queries
, nhưng đây là:
Tôi khuyên bạn nên xem mã đằng sau assert_queries
và sử dụng phương pháp đó để xây dựng phương pháp của riêng bạn mà bạn có thể sử dụng để đếm các truy vấn. Phép thuật chính liên quan ở đây là dòng này:
ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
Sáng nay, tôi đã có chút kỳ công và tách ra các phần của ActiveRecord để thực hiện việc đếm truy vấn và đưa ra kết quả này:
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ạn sẽ có thể tham chiếu đến ActiveRecord::Base.count_queries
phương pháp ở bất cứ đâu. Chuyển cho nó một khối trong đó các truy vấn của bạn được chạy và nó sẽ trả về số lượng truy vấn đã được thực thi:
ActiveRecord::Base.count_queries do
Ticket.first
end
Trả lại "1" cho tôi. Để làm cho việc này hoạt động:hãy đặt nó vào một tệp tại lib/active_record/query_counter.rb
và yêu cầu nó trong config/application.rb
của bạn tệp như thế này:
require 'active_record/query_counter'
Này presto!
Một chút giải thích có lẽ là cần thiết. Khi chúng tôi gọi dòng này:
ActiveSupport::Notifications.subscribe('sql.active_record', ActiveRecord::QueryCounter.new)
Chúng tôi kết hợp với khung thông báo nhỏ của Rails 3. Đó là một bổ sung nhỏ sáng bóng cho phiên bản chính mới nhất của Rails mà không ai thực sự biết về nó. Nó cho phép chúng tôi đăng ký nhận thông báo về các sự kiện trong Rails bằng cách sử dụng subscribe
phương pháp. Chúng tôi chuyển trong trường hợp chúng tôi muốn đăng ký làm đối số đầu tiên, sau đó bất kỳ đối tượng nào phản hồi call
như thứ hai.
Trong trường hợp này khi một truy vấn được thực thi, bộ đếm truy vấn nhỏ của chúng tôi sẽ tăng đáng kể biến ActiveRecord ::QueryCounter.query_count, nhưng chỉ đối với biến real truy vấn.
Dù sao, điều này rất vui. Tôi hy vọng nó hữu ích cho bạn.