在Sinatra和Rails之间共享Yaml配置文件

时间:2013-08-19 18:43:24

标签: ruby-on-rails ruby sinatra

我正在从现有的Rails应用程序中将Sinatra应用程序提取到一个gem中,以便在同一个Rails应用程序中重用。我想在其Rails.root/config(标准点)的当前位置保留一个配置文件,但仍然可以从Sinatra应用程序中使用它。我该如何干净利落地做到这一点?

目前Sinatra应用程序settings.root指向供应商目录深处的某个路径。我认为这是因为Sinatra应用程序是一个宝石。这意味着我必须猜出许多目录才能找到Rails应用程序的根目录。

有没有一种标准的方法来获取我的Sinatra应用程序所在的主要Rack应用程序的根目录?

3 个答案:

答案 0 :(得分:1)

没有干净的方法,因为应用程序是完全不同的堆栈。

您可以使用服务器的操作系统对Sinatra代码进行操作,这是我们的工作。

如果您使用的是Linux或Mac OS,请为您的Sinatra应用程序创建一个指向Rails配置文件的软链接。您可以编写一个创建它的rakefile,并在安装代码时运行该脚本。

在操作系统级别,您要使用:

ln -s path_to_rails_file.yaml path_to_sinatra_file.yaml

您甚至可以为Rails和Sinatra的YAML文件创建软链接,这些文件指向父目录或/ etc某处的文件的单个实例。你会想在适当的地方添加一些自述文件来记录软链接的使用,或者你会在凌晨3点讨厌自己,因为你不记得你为什么这么做了。

答案 1 :(得分:0)

如果您通过在config/routes.rb中添加条目来添加Sinatra应用,则可以在mount来电之前通过调用方法对其进行配置。

您在此处调用的任何方法都会在应用中的任何configure块之后运行,因此如果您想要做一些比设置单个变量更复杂的事情(使用Sinatra {{1你需要添加一个可以从set调用的类方法。

例如,如果您想要一个包含条目routes.rb的Yaml配置文件,那么在您的Sinatra应用程序中添加如下内容:

foo

现在def self.config_from_file(filename) data = YAML.load_file(filename) set :foo, data['foo'] # set other vars from Yaml as appropriate end 将在您的路线中提供。

在您的Rails settings.foo中,您需要添加以下内容:

config/routes.rb

答案 2 :(得分:0)

如果您通过将其添加为中间件而在Rails应用程序中包含Sinatra应用程序,那么您可以在配置它的应用程序中添加构造函数。 Sinatra有initialize method跟随常见的Rack中间件接口,第一个参数是将请求传递给的应用程序。通过在子类中重写它,您可以执行任何所需的配置。

例如,在您的Sinatra应用程序中:

def initialize(app, config_file)
  super(app)
  data = YAML.load_file(config_file)
  settings.foo = data['name']
end

为了调用settings.foo,您需要在配置块中为foo设置默认值,因为initialize方法在实例范围内运行该类的权限,并且无法访问set方法:

configure do
  set :foo, nil
end

现在您可以在application.rb中添加中间件(或者您想要添加的位置),如下所示:

config.middleware.use MyApp, File.join(Rails.root, "config/foo_settings.yaml")

如果您想在您的Rails应用程序之外安装Sinatra应用程序,您可以使用普通config.ruuse中执行类似操作。如果您在需要Rails应用的行之后添加use行,您仍然可以使用Rails.root变量。