Добавление в ActiveRecord::ConnectionAdapters::MysqlAdapter

Для общих знаний и развлекательных целей я пытаюсь добавить некоторое поведение в Rails. То, что я ищу, - это просто запустить оператор Mysql "EXPLAIN" перед каждым оператором select, который запускается Rails. Я думаю, что это должно работать нормально, но я получаю сообщение об ошибке:

/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/module/aliasing.rb:32:in alias_method': undefined methodselect_with_explain для класса `ActiveRecord::ConnectionAdapters::MysqlAdapter' (NameError)

Этот класс находится в каталоге инициализаторов. Вот код:

    module Explanifier

      def self.included(base)

        base.class_eval do
          extend ClassMethods
          alias_method_chain :select, :explain


        end
      end
      module ClassMethods
        def select_with_explain(sql, name = nil)
          puts "testing!!!"
          execute('EXPLAIN ' + sql, name)
          select_without_explain(sql, name)
        end
      end

    end



    class ActiveRecord::ConnectionAdapters::MysqlAdapter
      include Explanifier
    end

Может кто-нибудь объяснить, что мне здесь не хватает?


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


Ответы (2)


поместите свой alias_method_chain в свой модуль ClassMethods. потому что вы определяете метод как classMethod и псевдоним InstanceMethod


    module Explanifier

      def self.included(base)

        base.class_eval do
          extend ClassMethods



        end
      end
      module ClassMethods
        def select_with_explain(sql, name = nil)
          puts "testing!!!"
          execute('EXPLAIN ' + sql, name)
          select_without_explain(sql, name)
        end
        alias_method_chain :select, :explain
      end

    end
person shingara    schedule 04.03.2010

Просто наткнулся на это.

Вы не можете вызвать его из base.class_eval и, очевидно, не можете поместить его в модуль ClassMethods. (Поскольку в модуле ClassMethods нет метода select, не так ли?)

Способ сделать это:

def self.included(base)
  base.extend ClassMethods
  class << base
    alias_method_chain :select, :explain
  end
end

Вам просто нужно получить к нему доступ через призрачный класс. Надеюсь, поможет.

person alg    schedule 06.04.2011