Rails::Railtie: проблема с созданием драгоценного камня Rails 3

Мне действительно не помешал бы другой взгляд на это, поэтому я решил опубликовать его здесь. Некоторое время назад я написал базовое расширение ActiveRecord для собственных образовательных целей. В последнее время я читал о Railties и подумал, что попытаюсь заставить его работать с Rails 3. Я подумал, что упакую его как драгоценный камень, чтобы также получить представление об этом процессе. Если я пропущу Railtie и просто сделаю это как традиционный обезьяний патч в папке инициализаторов, он будет работать нормально. Используя Railtie... ничего.

Судя по всему, мой Railtie никогда не выполняется, и, следовательно, больше ничего не происходит.

Кто-нибудь видит здесь что-то не так?

Любые предложения по передовому опыту или улучшениям также приветствуются.

Gemfile проекта:

gem 'sql_explain', :path => "/home/mike/projects/sql_explain/"

спецификация драгоценных камней:

...
  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

person mikewilliamson    schedule 13.09.2010    source источник


Ответы (2)


Похоже, вы уже разобрались с этим, но помните, что с Rails 3 вы можете сделать:

ActiveSupport.on_load :active_record do
  ActiveRecord::ConnectionAdapters::MysqlAdapter.include SqlExplain::AR
end

Это гарантирует, что ваше включение будет запущено только после загрузки ActiveRecord.

person PreciousBodilyFluids    schedule 27.09.2010
comment
Я никогда не мог заставить метод инициализатора срабатывать в моем рельсе. Любые советы по этому поводу? - person mikewilliamson; 27.09.2010
comment
Мне ничего не кажется неправильным. Вы уверены, что загружается сам Railtie? - person PreciousBodilyFluids; 27.09.2010
comment
Рельс есть. ActiveSupport.onload внутри рельсы работает без проблем. Все, что находится внутри блока инициализатора, никогда не срабатывает. Документы создают впечатление, что они просто вызываются автоматически... - person mikewilliamson; 28.09.2010

Вы уверены, что это правда?:

if defined?(ActiveRecord)

Я полагаю, что это ложь. Вместо "rails" попробуйте указать "rails/all" - первый не загружает AR.

person gertas    schedule 13.09.2010
comment
Спасибо, Гертас, я еще раз взглянул на требования и думаю, что теперь он работает правильно ... может быть. - person mikewilliamson; 21.09.2010