3

tl;博士

我正在尝试将更大的应用程序的一部分分解为可安装的引擎。该引擎将以不同的风格存在,每种风格都包含在自己的 gem 中。我无法让 gem 名称与引擎常量名称不同。

细节

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

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

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

这样我们就可以在 Gemfile 中包含正确的 gem,其余的都可以正常工作,因为无论运行什么版本,它应该路由到的端点总是相同的。

问题

我遇到的问题是我无法让 gem 有一个名字,而引擎却是另一个名字......

如果我生成一个新的引擎名称身份验证,它可以很好地安装在主应用程序中。如果我然后将 gem 名称和包含文件夹更改为 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"...

我查看了整个源代码树,试图找到它从 gem 名称中推断出名称的位置,但我看不到它。我不知道我错过了什么,gem spec 文档对此也没有太大帮助......我不认为 gem 名称绑定到 gem 的常量名称,但也许我是错误的?你能覆盖它吗?还是我错过了其他东西?

4

1 回答 1

5

答案是简单地将其添加到主机应用程序 Gemfile: 中的行中gem 'auth_a', path: "../auth_a", require: 'auth'

所以看起来它默认为要求,即自动加载,一个基于 gem 名称的常量,但 require 调用告诉它需要什么。

希望它也对其他人有所帮助:)

于 2013-03-19T15:26:59.350 回答