Как код обезьяны-патча, который автоматически загружается в Rails?

Я обезьяна-исправляю двигатель Rails с чем-то вроде:

SomeClass.class_eval do
  # ...
end

В первый раз, когда я попал на веб-сайт, по крайней мере, в режиме разработки, он работает, но во второй раз он, как и мой патч, никогда не существовал. Я предполагаю, что Rails автоматически перезагружает двигатель (который установлен в поставщике /) и не перезагружает мой код. Это Rails 2.3.

Любые идеи, как это сделать, чтобы мой код также перезагружался?

Ответы

Ответ 1

EDIT: это решение работает только для Rails 3+, поскольку оно зависит от некоторых функций в Rails:: Railtie. Поместите этот код в инициализатор.

Этот вопрос довольно старый, но вот решение, которое я нашел:

Rails.configuration.to_prepare do
  SomeClass.class_eval do
    # ...
  end
end

Это заставляет Rails перезагружать класс по каждому запросу в режиме разработки, но только один раз в процессе производства.

Ответ 2

Я только что написал свой первый патч обезьяны, и поэтому ему нужно было создать набор условностей. Вот что я придумал:

  • Поместите расширения в lib/ext/. (Предлагается ветераном workmad3 в комнате IRС#rubyonrails.) В моем случае я добавляю метод к классу Mail::Message (из драгоценного камня mail, используемого ActionMailer), поэтому я создал:

    /lib/ext/mail/message.rb

  • Откройте класс или модуль и добавьте код:

    module Mail class Message def to_is_phone? !!(self.to.first =~ /^\+1\d{10}$/) end end end

  • Создайте инициализатор, чтобы загрузить все ваши патчи. Rails будет автозагружать файл при указании константы, но поскольку вы добавляете методы к существующим классам/модулям, а не определяете новые, это не сработает, поэтому вам придется вручную потребовать все ваши патчи-обезьяны. Поэтому я создал:

    /config/initializers/monkey_patches.rb

    Что содержит:

    require 'ext/mail/message'

Ответ 3

Если вы поместите патч в любой файл .rb внутри /config/initializers, он должен работать.

Ответ 4

К сожалению, нет способа подключиться к механизму перезагрузки Rails 2.x. То, что вы могли бы сделать, - это разместить патч в каталоге приложения или lib. (lib/core_ext, вероятно, является предпочтительным местом). Затем добавьте каталог в autoload_paths в ваш config.

Вам также может потребоваться открыть класс, а не использовать class_eval.

Ответ 5

Это некрасиво, но я обнаружил, что если я помещаю этот код в нижнюю часть environment.rb, он всегда гарантирует правильный порядок загрузки при запуске.

Ответ 6

Посмотрите, как этот драгоценный камень обрабатывает "украшение", ака-обезьяна исправляет что-то в двигателе или наоборот:

https://github.com/EPI-USE-Labs/activesupport-decorators