面向运行时错误NameError(未初始化的常量)模块,在从4​​.2.5.1升级到5.0.0.1之后放置在lib文件夹中的类

时间:2016-10-18 13:49:50

标签: ruby-on-rails-5 nameerror

我有两个单独的Rails应用程序

  • 只会暴露一个API(以下称为 API-app )和

  • 另一个充当管理门户(以下称为 AdminPortal ),用于管理API-app中的数据。

目前,两者目前都在登台以及生产环境中的Rails 4.2.5.1 上运行。但是,在 staging_experimental 环境中,我将两个应用程序升级到Rails 5.0.0.1 。我有两个应用程序和规范套件的rspecs,两个应用程序都在传递,Capistrano部署成功。但是,当尝试向API-app中的API端点发送请求时,我面临运行时错误

  

NameError(未初始化的常量Api :: BaseController :: ApiTokenAuthentication)

/lib/api_token_authentication.rb

module ApiTokenAuthentication
  <some module_functions defined here>
end

以下列方式在我的控制器中访问模块功能:

class Api::BaseController < ActionController::Base
  def authenticate!(user)
     ApiTokenAuthentication.my_module_function_here(user)
  end
end

AdminPortal中也会遇到同样类型的运行时错误 NameError(未初始化的常量...)错误,它们引用AdminPortal代码库的 lib 中的代码夹。例如,

  

NameError(未初始化的常量MyApiApp :: Api):

     

NameError(未初始化的常量MyApiApp :: Api :: Get):

     

NameError(未初始化&gt;常量MyApiApp :: Api :: Post):

/ LIB / my_api_app

/lib/my_api_app/api.rb

module MyApiApp
  module Api
  end
end

/lib/my_api_app/api/get.rb

module MyApiApp
  module Api
    class Get < BaseRequest
    end
  end
end

/lib/my_api_app/api/post.rb

module MyApiApp
  module Api
    class Post < BaseRequest
    end
  end
end

/lib/my_api_app/api/base_request.rb

module MyApiApp
  module Api
    class BaseRequest
    end
  end
end

/lib/my_api_app/api/base_response.rb

module MyApiApp
  module Api
    class BaseResponse
    end
  end
end

正在寻找解决这些错误的解决方案,我发现post后面提到明确要求初始化文件中的路径。例如,

/config/initializers/load_my_api_app_api_utility_classes.rb

require File.join(Rails.root, "lib/my_api_app/api.rb")

lib_api_dir_path = Rails.root.join("lib", "my_api_app", "api").to_s

Dir["#{lib_api_dir_path}/*.rb"].each {|file| require file }

添加上述初始化程序后,AdminPortal应用程序中的错误消失了

  

NameError(未初始化的常量MyApiApp :: Api):

     

NameError(未初始化的常量MyApiApp :: Api :: Get):

     

NameError(未初始化&gt;常量MyApiApp :: Api :: Post):

但是,只要AdminPortal应用程序向API-app公开的终端发送请求,我就开始遇到以下错误(前面提到过)

  

NameError(未初始化的常量Api :: BaseController :: ApiTokenAuthentication)

所以我认为有一些基本的东西缺失,导致与自动加载驻留在 lib 文件夹中的代码相关的错误,并且由控制器类使用。我真的很困惑为什么会这样,因为我已经检查/config/application.rb并且两个应用程序config.autoload_paths << Rails.root.join('lib')已经存在。

相同的代码在登台生产环境中没有任何问题,其中应用程序在Rails 4.2.5.1上运行。

在本地计算机上的开发环境中,升级代码也不会遇到这些错误。

有人可以阐明这一点,并指导我解决这个奇怪的错误吗?

更新 - 2016年10月19日

我在上面的问题中收到了以下回答here

  

在启用了eager_load的任何环境中都禁用了自动加载功能。   您永远不应该将lib添加到autoload_paths。使用eager_autoload_paths。   所有这些信息都在升级指南中进行了解释   http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#autoloading-is-disabled-after-booting-in-the-production-environment

我尝试使用eager_load_paths方法,但它开始抛出新错误。由于我在使用eager_load_paths后需要分享很多细节,因此我已将它们添加到要点here

希望尽快收到一些指导。

感谢。

1 个答案:

答案 0 :(得分:0)

最后,我发现无需向autoload_paths添加任何内容,也无需向eager_load_paths添加任何内容,也无需向config.enable_dependency_loading = true明确添加/config/environments/.rb

原因是实用程序代码,它本应在生产类型的环境中急切加载,即生产,登台等移动到app文件夹下的目录,如https://stackoverflow.com/a/19852844/936494所述< / p>

Another interesting quirk is that in every rails app, all directories under app/ are
automatically in both autoload_paths and eager_load_paths, meaning that adding a directory there requires no further actions.

这样我们就可以自动摆脱像NameError (uninitialized constant MyNamespace::Api)那样的运行时错误。

感谢。