现在我有一个连接数据库的简单Sinatra应用程序。
现在我在repo本身内部有硬编码的连接字符串。我的目标是从不同的文件(最终将在repo之外)返回连接信息。
这是我迄今为止所尝试过的:
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中包含配置文件?
答案 0 :(得分:2)
你是不对的,因为你不能以这种方式从return
d文件中require
at least not at the moment)。您的解决方案是使用顶级常量而不是全局变量(全局变量看起来像$foo
,常量看起来像Foo
或FOO
)但它几乎相同。
在Sinatra中进行此类配置的常见解决方案是使用ConfigFile
from Sinatra-contrib。
创建配置Yaml文件:
production:
mongourl: mongodb://localhost/prod
mongodb: prod
develepment:
mongourl: mongodb://localhost/dev
mongodb: prod
test:
mongourl: mongodb://localhost/test
mongodb: test
然后在你的Sinatra文件中(首先安装sinatra-contrib gem):
require 'sinatra'
require 'sinatra/config_file'
config_file 'path/to/config.yml'
现在,配置文件中的设置将根据正在运行的环境提供。
执行此类操作的另一种方法是将所有配置数据放入环境变量中,然后使用ENV
访问它们。这样做可以防止您意外地将生产凭据签入到版本控制中,但这意味着您必须以某种方式管理所有配置变量。如果您想这样做,请查看dotenv或Foreman以获取可以提供帮助的工具。
答案 1 :(得分: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
答案 2 :(得分: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
不是将连接字符串放在全局变量中的超级粉丝,但我认为它现在可以正常工作。如果有人有更好的方法来包含数据库连接字符串,请分享!