10

Để theo dõi một số vấn đề về hiệu suất, tôi đang cố gắng tạo một trang được hiển thị thông qua khung Rails (2.3.8) nhưng không thực hiện bất kỳ cuộc gọi nào đến cơ sở dữ liệu.Rails - làm thế nào tôi có thể thực hiện một yêu cầu mà không đánh cơ sở dữ liệu?

Tôi muốn yêu cầu đi qua phần mềm trung gian điển hình (routes.rb> controller> view), trái với việc hiển thị một trang tĩnh đơn giản (như 404.html) và trong nó sẽ hoạt động khi máy chủ db được bật tắt (máy chủ web vẫn đang chạy). Trang kết xuất thực tế là một trang html đơn giản hiển thị thời gian tiền tệ bằng cách sử dụng erb. Ngay bây giờ tôi nhận được lỗi khi tôi tắt cơ sở dữ liệu, và tôi có thể nhìn thấy 2 truy vấn mà vẫn được thực hiện:

SQL (0.1ms) SET NAMES 'utf8' 
SQL (0.1ms) SET SQL_AUTO_IS_NULL=0 

Bất kỳ ý tưởng làm thế nào để ghi đè lên các db hoàn toàn trong khi thực hiện yêu cầu đó? cảm ơn.

Trả lời

13

Cách duy nhất để khắc phục nó là ghi đè hàm configure_connection trong ActiveRecord. Để làm điều này, tôi khuyên bạn nên tạo một hàm ApplicationController có tên là skip_sql? để kiểm tra xem bạn có muốn bỏ qua chức năng configure_connection đối với một số bộ điều khiển # kết hợp hành động:

 
class ApplicationController 
    def skip_sql? 
    params[:controller] == "..." && params[:action] == "..." 
    end 
end 

Sau đó thực hiện chức năng này có sẵn cho các lớp học và các mô hình của bạn:

 
module SkipSql 
    module Controller 
    def self.included(base) 
     base.prepend_before_filter :assign_skip_sql_to_models 
    end 

    def assign_skip_sql_to_models 
     ActiveRecord::Base.skip_sql_proc = proc {send(:skip_sql?)} 
    end 
    end 
    module Model 
    def self.included(base) 
     base.extend ClassMethods 
    end 

    module ClassMethods 
     attr_accessor :skip_sql_proc 

     def skip_sql? 
     ActiveRecord::Base.skip_sql_proc.call if ActiveRecord::Base.skip_sql_proc 
     end 

    end 

    def skip_sql? 
     self.class.skip_sql? 
    end 
    end 
end 

Object.send :include, SkipSql::Model::ClassMethods 
ActionController::Base.class_eval {include SkipSql::Controller} 

Sau đó, bỏ qua sql chỉ trên bộ điều khiển # các kết hợp hành động bạn đã đặt:

 
class ActiveRecord::ConnectionAdapters::MysqlAdapter 
    def configure_connection 
    unless skip_sql? 
     encoding = @config[:encoding] 
     execute("SET NAMES '#{encoding}'", :skip_logging) if encoding 

     execute("SET SQL_AUTO_IS_NULL=0", :skip_logging) 
    end 
    end 
end 

Nếu cấu hình kết nối không hoạt động, tôi sẽ thử phương pháp kết nối như sau:

 
class ActiveRecord::ConnectionAdapters::MysqlAdapter 
    alias :old_connect :connect 

    def connect 
    old_connect unless skip_sql? 
    end 

    alias :old_active? :active? 

    def active? 
    skip_sql? ? false : old_active? 
    end 
end 

Tôi tin rằng phương thức kết nối sẽ được gọi trước phương pháp kết nối cấu hình, vì vậy nó sẽ giúp giải quyết vấn đề socket.

+1

Wow, cảm ơn. Tôi đã thử nó, nhưng tôi nhận được một lỗi kết nối 'Không thể kết nối với máy chủ MySQL cục bộ thông qua socket..' khi tôi tắt máy chủ cơ sở dữ liệu và thực hiện yêu cầu đó. Khi máy chủ db được bật, bây giờ tôi nhận được 'skip_logging' trong đó' SQL' trước đó là trên đầu ra mà tôi đã đưa ra ở trên. Tôi sẽ tiếp tục chơi với nó, trừ khi bạn nghĩ rằng tôi đang làm điều gì đó sai trái. cảm ơn một lần nữa! – sa125

+1

Xin chào, cũng cho phương pháp kết nối. Tôi cũng đã thêm mã cho điều đó. Hãy chắc chắn rằng đây là trong config/initializers của bạn hoặc autoload_once_path vì bạn sẽ không muốn tiếp tục tải lại mã này trong quá trình phát triển. –

+1

Tôi ước tôi có thể upvote câu trả lời của bạn lần thứ hai. Tôi khá chắc chắn điều này có thể làm cho một plugin tốt đẹp. – Jean

Các vấn đề liên quan