Gem规范名称必须与Gem常量名称相同吗?

4

tl;dr

我试图将一个大型应用程序中的一部分作为可挂载引擎拆分出来。引擎将以不同的风味存在,每种风味都包含在自己的宝石中。我无法使宝石名称与引擎常量名称不同。

详情

提取的部分包含注册、身份验证和会话处理的逻辑。该应用程序由不同地区的客户使用,他们对使用产品的最终客户有不同的要求和规定。这促使我们为每个监管地区的这些需求创建单独的模块。它们目前位于lib目录中,并根据配置加载不同的实现。

引擎的目标是,您安装适当的引擎,路由文件将所有相关调用路由到引擎。

由于我们有几个这样的注册模块,而且还有更多要来的,因此我们需要维护几个变体的宝石。我试图使宝石具有不同的名称(auth_A、auth_B等),但包含的引擎具有相同的常量名称Auth::Engine。

这样,我们可以在Gemfile中包含正确的宝石,其余部分将正常工作,因为无论运行哪个版本,它应路由到的终点始终相同。

问题

我遇到的问题是,我似乎无法使宝石具有一个名称,引擎常量具有另一个名称...

如果我生成一个名为auth的新引擎,则在主应用程序中挂载它就可以正常工作。如果我然后更改宝石名称和包含文件夹以auth_a,并更新主机应用程序的Gemfile,则停止工作,我可以很好地捆绑,但当我尝试启动主机应用程序并将其挂载到引擎时,它会失败,并抱怨Auth::Engine是未定义的常量。

我的略微删减的gemspec如下:

$:.push File.expand_path("../lib", __FILE__)

# Maintain your gem's version:
require "auth/version"

# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
  s.name        = "auth_a"
  s.version     = Auth::VERSION
  s.authors     = ["Jonas Schubert Erlandsson"]
  s.email       = ["jonas.schubert.erlandsson@xxxxxx.com"]
  s.homepage    = "http://some.page.on/the/internet.html"
  s.summary     = "Authentication module for A"
  s.description = "This engine, when mounted in Host app, handles registration, account update, login and logout of users."

  s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
  s.test_files = Dir["test/**/*"]

  s.add_dependency "rails", "~> 3.2.13"
end

我从生成的脚手架中唯一改变的是s.name = "auth_a"。主应用程序Gemfile中相关的行:gem 'auth_a', path: "../auth_a"...
我已经查看了整个源代码树,试图找到它从宝石名称推断名称的地方,但我找不到。我不知道我错过了什么,对于这个问题,宝石规范文档也没有提供太多帮助...我认为宝石名称并不绑定到宝石的常量名称,但也许我错了?你可以覆盖它吗?还是我错过了其他东西?
1个回答

6
答案很简单,只需在宿主应用的Gemfile中添加以下内容:gem 'auth_a', path: "../auth_a", require: 'auth'
似乎默认情况下会根据宝石名称自动加载常量,但require调用要求它加载指定内容。
希望对其他人也有所帮助 :)

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