2014-10-20 88 views
2

现在我已经有了一个简单的连接到数据库的Sinatra应用程序。从需求获取数据库配置

现在我有连接字符串硬编码回购本身内。我的目标是从不同的文件中返回连接信息(最终会在回购站之外)。

这是我到目前为止已经试过:

app.rb

class MySinatraApp < Sinatra::Application 

    configure do 

    conf = require_relative 'configuration' 

    # set public dirs, sessions, etc. 

    set :mongourl, conf[:mongourl] 
    set :mongodb, conf[:mongodb] 
    end 
end 

...终于在configuration.rb

env = ENV['RACK_ENV'].to_sym 

case env 
when :production 
    return { 
    "mongourl" => 'mongodb://localhost/prod', 
    "mongodb" => 'prod' 
    } 

when :development 
    return { 
    "mongourl" => 'mongodb://localhost/dev', 
    "mongodb" => 'prod' 
    } 

else 
    return { 
    "mongourl" => 'mongodb://localhost/test', 
    "mongodb" => 'test' 
    } 
end 

的想法是只返回任何哈希我需要使用,但是当我尝试上述时,它会出现这些错误:

<my_project_dir>/configuration.rb: <my_project_dir>/configuration.rb:9: Invalid return (SyntaxError) 
<my_project_dir>/configuration.rb:16: Invalid return 
<my_project_dir>/configuration.rb:21: Invalid return 

从错误中,您无法返回我现在正在执行的操作。我假设这是因为它不在某种函数调用中?人们通常如何在Ruby/Sinatra中包含配置文件?

回答

2

你是对的,你不能这样做,因为你不能这样从require d文件returnat least not at the moment)。您的解决方案是使用顶级常量而不是全局(全局变量看起来像$foo,常量看起来像FooFOO),但它几乎相同。

在Sinatra中执行此类配置的常见解决方案是ConfigFile from Sinatra-contrib。在西纳特拉

production: 
    mongourl: mongodb://localhost/prod 
    mongodb: prod 
develepment: 
    mongourl: mongodb://localhost/dev 
    mongodb: prod 
test: 
    mongourl: mongodb://localhost/test 
    mongodb: test 

然后文件(安装sinatra-contrib gem第一):

创建一个配置YAML文件

require 'sinatra' 
require 'sinatra/config_file' 

config_file 'path/to/config.yml' 

从配置文件中的设置现在将根据任何可用环境正在运行。

做这种事情的另一种方法是将所有配置数据放入环境变量,然后用ENV访问它们。这样做可以防止您意外地将生产凭证检入您的版本控制,但这意味着您必须以某种方式管理所有配置变量。看看dotenvForeman的工具,可以帮助你,如果你想这样做。

+0

真棒,谢谢你写了!我确实不得不随身带着这个应用程序来让它工作,但那是我自己的错误,而不是你的解释。谢谢您的帮助! – 2014-10-20 21:24:19

0

看来我可以在require'ed文件的根目录下声明一个变量,它自动是全局的(我认为)。在这两种情况下,这是我改变了文件的工作:

app.rb

class MySinatraApp < Sinatra::Application 

    configure do 

    require_relative 'configuration' 

    # set public dirs, sessions, etc. 

    set :mongourl, CONFIG["mongourl"] 
    set :mongodb, CONFIG["mongodb"] 
    end 
end 

configuration.rb

env = ENV['RACK_ENV'].to_sym 

case env 
when :production 
    CONFIG = { 
    "mongourl" => 'mongodb://localhost/prod', 
    "mongodb" => 'prod' 
    } 

when :development 
    CONFIG = { 
    "mongourl" => 'mongodb://localhost/dev', 
    "mongodb" => 'prod' 
    } 

else 
    CONFIG = { 
    "mongourl" => 'mongodb://localhost/test', 
    "mongodb" => 'test' 
    } 
end 

由于没有连接字符串中的一个全局变量是一个超级大风扇,但现在我认为它会起作用。如果有人有更好的方式来包含数据库连接字符串,请分享!

1

如果有人有更好的方式来包含数据库连接字符串,请分享!

我不会说这是一种更好的方式,但我这样做是因为它很简单。 或多或少与sinatra/config_file相同。

所以,你必须与不同的价值观您的配置文件为每个环境

$cat config.yaml 
development: 
    mongourl: mongodb://localhost/test 
    mongodb: dev 
production: 
    mongourl: mongodb://localhost/test 
    mongodb: prod 

而现在只需要使用它:

configure do 
    env = ENV['RACK_ENV'] 
    AppConfig = YAML.load_file(File.expand_path("../config.yaml", File.dirname(__FILE__)))[env] 
    set :mongourl, AppConfig['mongourl'] 
    set :mongodb, AppConfig['mongodb'] 
end