控制作为引擎提取的应用程序的Rails初始化

时间:2011-06-14 01:16:08

标签: ruby-on-rails-3.1

我希望将Rails应用程序既可用作引擎又可用作独立应用程序。

具体来说,我有一个新生的应用程序,我想插入客户的网站,但理想情况下,我想轻松使用该应用程序作为一个独立的系统。但是,如果我的应用程序的引擎版本中存在config / environments / * .rb,那么当我对我的引擎具有依赖性的应用程序启动时,我会收到未初始化的常量错误; Rails抱怨在developer.rb中找不到MyEngineModule :: Application常量,我认为这只是一个加载顺序问题,因为当我独立运行app时不会发生这种情况。如果我删除了development.rb,引用我的MyEngineModule :: Application的原始初始化程序会抱怨,所以我试图删除它们,一切都很好。

很好,除了原始应用程序不起作用,因为它的配置已经消失。

我是否可以对初始化加载顺序(或引擎< Rails :: Engine类定义中的加载路径)进行一些调整,以防止在引擎上下文中加载原始配置和初始化程序,并且允许我将它们留在应用程序上下文中吗?

更简单的答案可能就是这个,但我感觉很顽固,并且想知道如何才能使我的原始目标成为可能:

  • 将MyEngine的代码解压缩到引擎中,删除config / environments / *文件和config / initializers / *文件,并使客户端应用依赖于此。
  • 制作一个依赖MyEngine的“新”极简主义应用程序,并将环境文件和初始化程序移至NewApp。

假设我感觉有些不自然的强迫让我的原始应用程序可以运行,如果我想阻止“引擎”加载“应用程序”配置,那么处理它的最佳方法是什么?我认为这只是开发过程中的一个问题,因为我可以阻止环境/ * .rb文件被拉入gem本身,但我喜欢能够在我开发引擎及其客户端应用程序时进行本地测试。

2 个答案:

答案 0 :(得分:6)

继续我回答我自己的深奥问题的传统,似乎一个可行的替代方案是在引擎的环境/ * .rb中包含一个保护条款和类似这样的初始化器:

if defined? CuteEngine::Application
  CuteEngine::Application.configure do
    config.whatever = something
  end
end

这解决了以相对较低的成本获得两个Rails :: Application对象的问题。对此不是很满意,但我会活下去。

答案 1 :(得分:1)

将此归咎于新来者。

Rails 3.1附带可安装的引擎,听起来就像你所描述的那样。这些文档不适合转换现有代码,但看起来这样做可以达到你想要的效果:

module CuteEngine
  class Engine < ::Rails::Engine
    isolate_namespace CuteEngine
  end
end

在您的其他应用的routes.rb文件中,您将添加:

mount CuteEngine::Engine, at: "/cuteness"

http://edgeguides.rubyonrails.org/engines.html#mounting-the-engine

http://railscasts.com/episodes/277-mountable-engines