Как код обезьяны-патча, который автоматически загружается в 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