Rails - 如何创建一个完全没有命中数据库的请求?

时间:2011-02-08 06:13:38

标签: mysql ruby-on-rails performance middleware function-overriding

为了追踪一些性能问题,我正在尝试创建一个通过Rails(2.3.8)框架呈现的页面,但不对数据库进行任何调用。

我希望请求通过典型的中间件(routes.rb> controller>视图),而不是渲染一个简单的静态页面(如404.html),并且当数据库服务器是关闭(Web服务器仍在运行)。实际呈现的页面是一个简单的html页面,使用erb显示货币时间。现在,当我关闭数据库时出现错误,我可以看到仍然有2个查询:

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

知道如何在发出请求时完全覆盖数据库吗?感谢。

1 个答案:

答案 0 :(得分:13)

绕过它的唯一方法是覆盖ActiveRecord中的configure_connection函数。为此,我建议创建一个名为skip_sql的ApplicationController函数?测试是否要跳过某些控制器#操作组合的configure_connection函数:

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

然后将此功能提供给您的课程和模型:

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}

然后仅在您设置的控制器#动作组合上跳过sql:

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

如果configure_connection不起作用,我会尝试这样的连接方法:

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

我相信在配置连接方法之前调用connect方法,因此它应该有助于解决套接字问题。