2012-10-21 2 views
3

У меня есть настройка рельсов, что-то вроде этого.Rails Load Class Изменения без перезапуска сервера

приложение/сервис/TestService.rb

class TestService 

    def self.doSomething 
    return 'Hello World!' 
    end 

end 

Я использую этот файл в контроллере.

require 'TestService' 

class IndexController < ApplicationController 

    def index 
    @message = TestService.doSomething 
    end 

end 

Я также добавил это в application.rb внутри папки config, так что рельсы автоматически загружают классы в служебную папку.

config.autoload_paths += %W(#{config.root}/app/service) 

Но приложение, похоже, не подбирает обновления для класса TestService. Как исправить это, чтобы изменения в классе TestService отображались без перезапуска сервера.

ответ

2

Не используйте require при попытке загрузить файл, содержащий перезаряжаемую константу.

Как правило, вам не нужно ничего делать, чтобы использовать эту константу. Вы просто будете использовать константу напрямую, без необходимости использовать require или что-нибудь еще.

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

require_dependency 'test_service' 

class IndexController < ApplicationController 
    ... 
end 

Хотя это сбивает с толку, что вы пытаетесь быть кристальной чистоты и явно загрузить файл, содержащий TestService, но явно не загрузить файл, содержащий ApplicationController ....

Вам не нужно менять autoload_paths конфигурации ,


Update 1

Для того, чтобы позволить Rails найти и загрузить свои константы (классы и модули), вам нужно сделать следующее:

Вы должны быть уверены, что каждый пополняемые постоянным в вашем приложение находится в файле с правильным именем файла. Файл всегда должен находиться в некотором подкаталоге app, например app/models или app/services или в любом другом поддиректории. Если константа называется TestService, имя файла должно заканчиваться test_service.rb.

Алгоритм: "TestService".underscore + ".rb" #=> "test_service.rb".

filename_glob = "app/*/" + the_constant.to_s.underscore + ".rb" 

Так что, если константа TestService, то Глоб является app/*/test_service.rb.Так что прилипание константы в app/services/test_service.rb будет работать, как и app/models/test_service.rb, хотя последняя плохая форма. Если константа была SomeModule::SomeOtherModule::SomeClass, вам нужно будет поместить файл в app/*/some_module/some_other_module/some_class.rb.

+0

Добавление require_dependency ... похоже, работает. Однако, если я удалю его, изменения в TestService не будут загружены. – 3coins

+0

Отменить изменение конфигурации 'autoload_paths'. Не устанавливайте эту конфигурацию вообще. – yfeldblum

+0

Я уже удалил это. Получите эту ошибку, если я не требую или require_dependency в контроллере. uninitialized constant IndexController :: TestService – 3coins

0

Вы говорите, что ваш файл находится в app/server, но вы автоматически загружаете app/service. Что правильно?

Переименуйте файл в app/service/test_service.rb, и автозагрузчик должен работать. Rails ищет файлы с именами snake_cased в ваших путях автозагрузки. Вам также не понадобится руководство require, если вы правильно выполнили автозагрузку.

+0

Моя ошибка, файл находится в приложении/службе, я обновил сообщение. – 3coins

Смежные вопросы