Rails 5 生产中的自动加载问题
Rails 5 autoloading issue in production
我很难理解 Rails 自动加载的问题。
所以我有一个位于名为 api
的文件夹中的控制器。控制器声明为 class Api::TestController
.
在另一个文件夹中,我有一个名为 app/my_folder/service_name/api.rb
的文件
在生产中,我得到这个错误:load_missing_constant': Unable to autoload constant Api, expected /app/my_folder/service_name/api.rb to define it (LoadError)
application.rb
有这一行:
config.autoload_paths += Dir[Rails.root.join('app', 'my_folder', '{**/}')]
我在开发中没有问题。
为什么会这样?
这是因为自动加载路径仅用于自动加载。为了让您的 class 在生产中加载,您还需要扩充 eager_load_paths
:
config.eager_load_paths += Dir[Rails.root.join('app', 'my_folder', '{**/}')]
然而,这并不是一个很好的做法 - app
中的任何目录都会自动用作根目录。您正在做的是将给定目录的每个子目录添加为根目录。
对 namespace definition should also be avoided as it leads to suprising constant lookup behavior and is the source of autoloading bugs. Instead you should nest the class explicitly and setup an inflection for the acronym 使用范围结果运算符 (class Api::TestController
):
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
# every time you use Api as a constant name a kitten dies.
module API
class TestController
puts Module.nesting.inspect # [TestController::API, API]
end
end
我很难理解 Rails 自动加载的问题。
所以我有一个位于名为 api
的文件夹中的控制器。控制器声明为 class Api::TestController
.
在另一个文件夹中,我有一个名为 app/my_folder/service_name/api.rb
在生产中,我得到这个错误:load_missing_constant': Unable to autoload constant Api, expected /app/my_folder/service_name/api.rb to define it (LoadError)
application.rb
有这一行:
config.autoload_paths += Dir[Rails.root.join('app', 'my_folder', '{**/}')]
我在开发中没有问题。
为什么会这样?
这是因为自动加载路径仅用于自动加载。为了让您的 class 在生产中加载,您还需要扩充 eager_load_paths
:
config.eager_load_paths += Dir[Rails.root.join('app', 'my_folder', '{**/}')]
然而,这并不是一个很好的做法 - app
中的任何目录都会自动用作根目录。您正在做的是将给定目录的每个子目录添加为根目录。
对 namespace definition should also be avoided as it leads to suprising constant lookup behavior and is the source of autoloading bugs. Instead you should nest the class explicitly and setup an inflection for the acronym 使用范围结果运算符 (class Api::TestController
):
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
# every time you use Api as a constant name a kitten dies.
module API
class TestController
puts Module.nesting.inspect # [TestController::API, API]
end
end