问题
I could really use another set of eyes on this so I thought I would post it here. A while ago I wrote a basic ActiveRecord Extension for my own educational purposes. I've been reading about Railties lately and thought I would try to get it working with Rails 3. I thought I would package it up as a gem to get a sense of that process as well. If I skip the Railtie and just do this as a traditional monkeypatch in the initializers folder it works fine. Using a Railtie... nothing.
From the looks of it my Railtie is never executed and therefore nothing else seems to be happening.
Does anyone see anything wrong here?
Any suggestions for best practices or improvements are also welcome.
project 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
回答1:
Looks like you've already got this sorted out, but remember that with Rails 3 you can do:
ActiveSupport.on_load :active_record do
ActiveRecord::ConnectionAdapters::MysqlAdapter.include SqlExplain::AR
end
That'll ensure that your include will only be fired once ActiveRecord has been loaded.
回答2:
Are you sure this is true?:
if defined?(ActiveRecord)
I suppose it is false. Instead of "rails" try to require "rails/all" - the first one is not loading AR.
来源:https://stackoverflow.com/questions/3702488/railsrailtie-trouble-creating-a-rails-3-gem