2014-10-20 89 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