Как обезопасить код, который автоматически загружается в Rails? - PullRequest
15 голосов
/ 16 декабря 2010

Я исправляю движок Rails чем-то вроде:

SomeClass.class_eval do
  # ...
end

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

Есть идеи, как сделать так, чтобы мой код также был перезагружен?

Ответы [ 6 ]

20 голосов
/ 06 октября 2011

РЕДАКТИРОВАТЬ: Это решение работает только для Rails 3+, поскольку оно зависит от некоторых функций в Rails :: Railtie. Поместите этот код в инициализатор.

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

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

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

7 голосов
/ 14 апреля 2014

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

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

    /lib/ext/mail/message.rb

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

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

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

    /config/initializers/monkey_patches.rb

    Который содержит:

    require 'ext/mail/message'

5 голосов
/ 07 июня 2011

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

0 голосов
/ 13 июня 2015

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

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

0 голосов
/ 12 июня 2011

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

0 голосов
/ 16 декабря 2010

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

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

...