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

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

SomeClass.class_eval do
  # ...
end

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

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


person pupeno    schedule 16.12.2010    source источник
comment
Однажды я столкнулся с подобной проблемой, и единственный способ, которым я мог ее исправить, — это запустить рельсы в производственном режиме на моей машине разработки :(. Меня это тоже интересует.   -  person kikito    schedule 16.12.2010
comment
@egarcia: ой, я надеюсь, что на этот раз мы сможем найти лучшее решение.   -  person pupeno    schedule 16.12.2010
comment
как вы запускаете свой код, это webbrick, дворняга или пассажир? пожалуйста, опубликуйте версии рельсов и сервера.   -  person mpapis    schedule 21.12.2010


Ответы (6)


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

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

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

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

person James H    schedule 06.10.2011
comment
У меня тоже работает в Rails 5. - person ttotherat; 28.03.2017

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

  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'

person odigity    schedule 14.04.2014
comment
Обратите внимание, что в настоящее время я использую Rails 4.1, но я думаю, что это должно работать и в более старых версиях. - person odigity; 14.04.2014
comment
monkey_patches.rbвместо этого может быть Dir[Rails.root.join('lib/ext/*.rb')].each { |file| require file } и все патчи обезьяны будут подобраны. - person Dan Kohn; 27.10.2014
comment
Двойная звездочка @DanKohn ftw! :) Dir[Rails.root.join('lib/ext/**/*.rb')].each { |file| require file } - person ermenkoff; 15.07.2021

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

person Fuad Omar    schedule 07.06.2011
comment
в чем разница с использованием class_eval и to_prepare? - person montrealmike; 14.10.2013

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

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

person iain    schedule 16.12.2010
comment
Обезьяна-патч уже находится в lib/, который уже есть в autoload_paths на Rails 2. Я не уверен, почему, но открытие класса с ключевым словом class вместо class_eval приводит к ошибке, а позже возникает исключение. - person pupeno; 16.12.2010

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

person Taryn East    schedule 12.06.2011

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

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

person Pierre Pretorius    schedule 12.06.2015