Rails重新加载类而无需重启服务器

3
我有一个类似于这样的Rails设置。
app/service/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个回答

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中。

添加 require_dependency ... 似乎有效。但是,如果我将其删除,则不会加载对 TestService 的更改。 - 3coins
撤销对autoload_paths配置的更改。根本不要设置该配置。 - yfeldblum
我已经删除了那个。如果控制器中没有require或require_dependency,就会出现这个错误:未初始化常量IndexController :: TestService。 - 3coins
总之,删除 require,将文件名更改为 snake_case - Chloe

0

你说你的文件在app/server,但是你正在自动加载app/service。哪个是正确的?

将你的文件重命名为app/service/test_service.rb,自动加载器就会起作用。Rails会在你的autoload路径中查找蛇形命名的文件名。一旦你正确地实现了自动加载行为,就不需要手动使用require了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接