Повторное открытие класса, расположенного в папке lib (Rails 3) - PullRequest
2 голосов
/ 03 марта 2011

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

У меня есть код ruby, расположенный в одном файле. Этот код представляет собой один модуль MyModule, который содержит несколько классов. Я не могу изменить этот код, потому что он автоматически генерируется внешним инструментом. Имя файла my_module.rb, и оно находится в папке lib. Это обычное место для кода, который не принадлежит основному веб-приложению. Я убедился, что он загружается автоматически, когда я получаю доступ к MyModule на одном из контроллеров моего приложения, изменив настройку config.autoload_paths в application.rb.

Теперь мне нужно заново открыть один из классов в MyModule. Я создал отдельный файл some_class.rb, куда я поместил следующий код:

    class MyModule::SomeClass
        def some_new_method
           ...
        end
    end

Мой вопрос: как лучше всего разместить этот код? А каким должно быть имя файла?

То, что я пробовал:

  1. Размещение кода в папке initializers. он отлично работает в производственной среде. Однако он ломается в development, потому что код в папке initiliazers загружается один раз при запуске сервера и lib перезагружается при каждом запросе. Итак, первый запрос в разработке работает нормально, однако последующие запросы терпят неудачу. Кроме того, я не люблю помещать код в initializers, потому что это на самом деле не часть инициализации, а скорее часть бизнес-логики.
  2. Размещение кода в папке lib также не работает. Это не загружено. Только my_module.rb есть.
  3. Поместите код в lib или другую папку в app, а затем явно requir в контроллеры. Опять же, он работает в производстве, но не развивается по той же причине, что и в случае № 1.
  4. Я отключил автоматическую загрузку, поместил my_module.rb и some_class.rb в папку lib и require отредактировал их в инициализаторе. Я думаю, что это лучший подход. Недостатком является то, что мне все еще нужно создать собственный инициализатор, и код не загружается лениво.

UPDATE: 5. Благодаря предложению Рэгги, с включенной автозагрузкой, я вставил require_dependency 'some_class' в свой контроллер. В этом случае some_class.rb загружается на каждый запрос в режиме разработки. Это мой предпочтительный подход. Тем не менее, он по-прежнему требует своего рода require:)

Помните, что файлы в папке lib загружаются автоматически. Rails проверяет папку только тогда, когда вы используете модули или классы, которые rails не может найти. Имя файла должно соответствовать соглашению об именах, поэтому имя my_module.rb.

Интересно, есть ли решение, когда оба файла автоматически загружаются без любых require операторов.

Ответы [ 3 ]

1 голос
/ 06 марта 2011

Вы пытались использовать require_dependency в вашем контроллере вместо require?

0 голосов
/ 13 сентября 2011

TL; DR: Скрыть require за пределами основного кода.

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

// Added to application.rb
Rails::Application.config.autoload_paths.each do |d|
  Dir["#{d}/*.rb"].each do |p|
    puts "Requiring '#{p}' on startup..."
    require p
  end
end
0 голосов
/ 03 марта 2011

Вы можете поместить файлы в каталог lib и загружать их не лениво, а автоматически, в config / application.rb, если вы хотите поместить файлы в разные подпапки:

config.autoload_paths += Dir["#{config.root}/lib/**/"]

Или, если вам нужнотолько папка lib:

config.autoload_paths += %W(#{config.root}/lib)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...