我真的可以用另一套眼睛,所以我想我会把它贴在这里。 不久之前,我为自己的教育目的写了一个基本的ActiveRecord扩展。我最近一直在阅读有关Railties的文章,并且我认为我会尝试使用Rails 3.我想我会把它打包成一块宝石来了解这个过程。 如果我跳过Railtie并在初始化文件夹中将其作为传统的monkeypatch执行,它可以正常工作。使用铁路......没什么。
从它的外观来看,我的Railtie永远不会被执行,因此似乎没有其他任何事情发生。
有人在这看错了吗?
欢迎任何有关最佳做法或改进的建议。
项目Gemfile:
gem 'sql_explain', :path => "/home/mike/projects/sql_explain/"
gemspec:
...
spec.files = %w(README.rdoc sql_explain.rb lib/sql_explain.rb lib/railtie.rb sql_explain.gemspec)
...
sql_explain.rb
require 'lib/railtie.rb'
railtie.rb
require 'active_record'
require 'sql_explain'
module SqlExplain
class Railtie < Rails::Railtie
railtie_name :sql_explain
initializer 'sql_explain.extend.activerecord' do
if defined?(ActiveRecord)
ActiveRecord::ConnectionAdapters::MysqlAdapter.include SqlExplain::AR
end
end
end
end
sql_explain.rb
module SqlExplain
module AR
def self.included(base_klass)
base_klass.send :alias_method_chain, :select, :explain
end
def select_with_explain(sql, name = nil)
@connection.query_with_result = true
result = execute('explain ' + sql, :skip_logging)
rows = []
result.each_hash { |row| rows << row }
result.free
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
exp_string = ""
rows.each{|row| row.each_pair{|k,v| exp_string += " #{k}: #{v} |"}}
log(exp_string, "Explanation") {}
select_without_explain(sql, name)
end
end
end
答案 0 :(得分:3)
看起来你已经解决了这个问题,但请记住,使用Rails 3,你可以做到:
ActiveSupport.on_load :active_record do
ActiveRecord::ConnectionAdapters::MysqlAdapter.include SqlExplain::AR
end
这将确保只有在加载ActiveRecord后才会触发您的包含。
答案 1 :(得分:1)
你确定这是真的吗?:
if defined?(ActiveRecord)
我认为这是假的。而不是“rails”尝试要求“rails / all” - 第一个不加载AR。