在 Rails 开发中加载类后代

jer*_*ink 7 ruby ruby-on-rails

当我在本地进入 rails 控制台时,我需要能够从控制器中看到所有类的后代。我有这个Api::BaseController,我所有的 Api 控制器都继承自。我遇到的问题是,当我跳入 rails 控制台以检查后代中的 Api 控制器时,它一直是空的,直到我调用它们。这可能与开发中的类如何不急切加载有关,并且它们不在本地缓存。

sample_app$ rails c
Loading development environment (Rails 4.2.0)
2.1.5 :001 > Api::BaseController.descendants
 => []
2.1.5 :002 > Api::V1::FoosController
 => Api::V1::FoosController
2.1.5 :003 > Api::BaseController.descendants
 => [Api::V1::FoosController]
Run Code Online (Sandbox Code Playgroud)

从这个例子中,你可以看到当我Api::BaseController第一次调用后代时,它是一个空数组。在调用其中一个控制器之后,该类将被加载并显示为后代。在这种情况下,V1 以及 V2、V3 等中可能有任意数量的控制器......

作为一个愚蠢的丑陋的黑客,我可以做到

Dir.glob("#{Rails.root.join('app', 'controllers', 'api', 'v1')}/**/*.rb").each(&method(:require_dependency))
Run Code Online (Sandbox Code Playgroud)

但我不想每次进入控制台时都必须写。我也在研究一个 gem,绝对不想把这种代码放在我的 gem 中。

另一种选择是在开发中缓存类,但这本身会导致巨大的问题。谁有想法?

编辑 另一种选择是调用Rails.application.eager_load!. 如果我只能在我的 API 文件夹中指定控制器,这个选项就可以正常工作。这样我就不必急切加载整个应用程序,而只需加载我需要的一小部分控制器。

Agu*_*ico 6

我找到了以下帖子:http : //avinmathew.com/using-rails-descendants-method-in-development/

简而言之,它说明了以下内容:

enviroments/development.rb添加以下内容:

config.eager_load_paths += Dir['path/to/files/*.rb']
ActionDispatch::Reloader.to_prepare do
  Dir['path/to/files/*.rb'].each {|file| require_dependency file}
end
Run Code Online (Sandbox Code Playgroud)

第一行添加了启动应用程序(或控制台)时应加载的路径,其余部分告诉 rails 在每个请求上重新加载类。

  • 如果您使用的是 Rails 5,重新加载部分现在应该如下所示: Rails.application.reloader.to_prepare do Dir["path/to/files/*.rb"].each {|file| require_dependency 文件} end (4认同)