这是我们的基本要求:
为此,我可以看到实现这一目标的几个选项:
Rails::Engine
Rails::Application
最明显的答案是Git分支,充分灵活。
但是我不确定这是不是一个好主意,因为代码库基本上是共享的,主线有更多的活动 - 赶上rebase / merge可能只是额外的麻烦。
我们希望尽可能地分离原始版本和自定义版本。换句话说,我们希望在原始和自定义之间尽可能减少冲突。
Rails::Engine
或Rails::Application
似乎是一个非常接近的想法(我不熟悉Rails引擎),但我不明白如何OurApp::Application
和OurCustomizedApp::Application
在一个地方,并在全球和动态之间切换它们。
可能会很高兴:
RAILS_APP
config/database.yml
为config/customer1/database.yml
deploy.rb
用于capistrano(可能与config/servers.yml
和config/customer1/servers.yml
一起定义角色和IP?)我们的要求是否有做法/惯例?有什么建议吗?
我们的应用程序在Ruby 1.9.2 + Rails 3.0.3上运行。
更新
我们将它作为Git分支开始。我们创建了一个rake任务来生成config/branch
的文件,其中包含“master”或“custom”等文本,application.rb在bootstrap时读取它。 database.yml
或servers.yml
等配置现在位于config/mainline/
或config/customized/
,而application.rb会相应地处理它们。
config.paths.config.database = "config/#{branch}/database.yml"
不完美,但现在还不错。当我们找到更好的方法时,我会更新。
答案 0 :(得分:2)
我认为最好的方法是以老式的方式做到这一点。
首先,将单个类添加到项目(/lib
)中,称为Affiliate
。此类应该为可以自定义的应用程序的任何部分提供默认实现(无论您希望基本应用程序使用什么)。此时,您的应用程序的功能相同,但具有允许自定义的挂钩。
在您客户的站点上,部署相同的源代码(可能是作为gem提供的?),还要部署覆盖Affiliate
的Rails插件,以便其单例instance
方法返回一个自定义子类,提供客户特定的信息或行为。
编辑添加:此方法的风险在于开发人员无意中破坏了因为他们只针对默认会员测试他们的更改。您应该使用自动化测试和持续集成来捕获它。
答案 1 :(得分:1)
我知道这不是你所追求的确切答案,但我相信Git将是最少的工作 - 并且最容易管理,长期 - 而不是定制应用程序并添加逻辑来处理额外的配置文件,修改部署文件以及管理(可能)新的css / js /模板文件。
使用rebase&合并将更容易出错,并且只要您定期同步分支机构,就不应该有任何严重的问题让它们保持最新状态。毕竟,这就是Git擅长的! ;)
答案 2 :(得分:1)
这里似乎有两个有趣的要求。您询问如何拥有两个单独的应用程序并动态切换它们。我假设您要共同托管同一应用程序的不同“版本”,并让应用程序根据域切换到不同的自定义项。然而,这与使用Git分支部署两个不同的应用程序非常不同。
您能否在此澄清您的要求?
我不会在这里推荐Git分支作为解决方案。我建议使用引擎。特别是将您的引擎捆绑成宝石。
将gem包含在Custom项目中,然后使用传统方法覆盖引擎中的功能。您还可以使用扩展现有Ruby代码的传统方法来覆盖gem中的功能。
通过这种方式,您可以将所有差异保留在单独的项目中。这个单独的项目也将拥有自己的一组测试等。
答案 3 :(得分:0)
我们经常使用Git来做这件事。