Rails加载类更改而不重新启动服务器

时间:2012-10-21 05:13:28

标签: ruby-on-rails ruby

我有一个类似这样的rails设置。

应用程序/服务/ TestService.rb

class TestService

  def self.doSomething
    return 'Hello World!'
  end

end

我在控制器中使用此文件。

require 'TestService'

class IndexController < ApplicationController

  def index
    @message = TestService.doSomething
  end

end

我还在config文件夹中的application.rb中添加了这个,以便rails在服务文件夹中自动加载类。

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

但是应用程序似乎没有获得TestService类的更新。我该如何解决这个问题,以便在不重新启动服务器的情况下显示TestService类中的更改。

2 个答案:

答案 0 :(得分:2)

尝试加载包含可重新加载常量的文件时,请勿使用require

通常,您不需要做任何特殊的事情来使用该常量。您只需直接使用常量,而无需使用require或其他任何内容。

但是如果你想用你的代码干净利落,ActiveSupport为你提供了一个不同的方法,可用来加载这些文件:require_dependency

require_dependency 'test_service'

class IndexController < ApplicationController
  ...
end

虽然令人困惑的是你会尝试干净并且明确加载包含TestService的文件但是没有显式加载包含ApplicationController的文件....

您无需更改autoload_paths配置。


更新1

为了让Rails找到并加载您的常量(类和模块),您需要执行以下操作:

您必须确保应用程序中的每个可重新加载的常量都位于具有正确文件名的文件中。该文件必须始终位于app的某个子目录中,例如app/modelsapp/services或任何其他子目录。如果常量名为TestService,则文件名必须以test_service.rb结尾。

算法为:"TestService".underscore + ".rb" #=> "test_service.rb"

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

因此,如果常量为TestService,则glob为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

答案 1 :(得分:0)

您说您的文件位于app/server,但您正在自动加载app/service。哪个是对的?

将文件重命名为app/service/test_service.rb,自动加载器应该可以正常工作。 Rails在自动加载路径中查找基于snake_cased的文件名。一旦您的自动加载行为正确,您就不需要手册require