Ruby 从require获取数据库配置

Ruby 从require获取数据库配置,ruby,sinatra,Ruby,Sinatra,现在我有一个简单的Sinatra应用程序,可以连接到DB 现在,我把连接字符串硬编码在回购协议中。我的目标是从不同的文件返回连接信息(最终将在回购协议之外) 这就是我迄今为止所尝试的: app.rb class MySinatraApp < Sinatra::Application configure do conf = require_relative 'configuration' # set public dirs, sessions, etc.

现在我有一个简单的Sinatra应用程序,可以连接到DB

现在,我把连接字符串硬编码在回购协议中。我的目标是从不同的文件返回连接信息(最终将在回购协议之外)

这就是我迄今为止所尝试的:

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
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
class MySinatraApp < Sinatra::Application

  configure do

    require_relative 'configuration'

    # set public dirs, sessions, etc.

    set :mongourl, CONFIG["mongourl"]
    set :mongodb,  CONFIG["mongodb"]
  end
end
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
想法是只返回我需要使用的任何哈希,但是当我尝试上述操作时,它会出现以下错误:

<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
/configuration.rb:/configuration.rb:9:返回无效(语法错误)
/配置.rb:16:返回无效
/配置.rb:21:返回无效

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

似乎我可以在
require
文件的根中声明一个变量,它自动是全局的(我认为)。无论哪种情况,我都是这样更改文件以使其工作的:

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
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
class MySinatraApp < Sinatra::Application

  configure do

    require_relative 'configuration'

    # set public dirs, sessions, etc.

    set :mongourl, CONFIG["mongourl"]
    set :mongodb,  CONFIG["mongodb"]
  end
end
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

我不太喜欢将连接字符串放在全局变量中,但我认为现在它可以工作了。如果有人有更好的方法包括数据库连接字符串,请分享

您不能这样做是对的,因为您不能以这种方式从
require
d文件返回
)。您的解决方案是使用顶级常量而不是全局常量(全局变量看起来像
$foo
,常量看起来像
foo
foo
),但这几乎是一样的

在Sinatra中进行此类配置的常见解决方案是使用

创建配置Yaml文件:

生产:
蒙古尔:mongodb://localhost/prod
mongodb:prod
发展:
蒙古尔:mongodb://localhost/dev
mongodb:prod
测试:
蒙古尔:mongodb://localhost/test
mongodb:测试
然后在Sinatra文件中(安装第一个):

根据运行的环境,配置文件中的设置现在可用

另一种方法是将所有配置数据放入环境变量中,然后使用访问它们。这样做可以防止您意外地将生产凭据签入到版本控制中,但这意味着您必须以某种方式管理所有配置变量。如果您想走这条路,请查看或寻找可以帮助您实现这一点的工具

如果有人有更好的方法包括数据库连接字符串,请分享

我不会说这是一个更好的方法,但我这样做是因为它很简单。 它或多或少与sinatra/config_文件相同

所以您的配置文件针对每个环境具有不同的值

$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 

太棒了,谢谢你的评论!我确实需要在应用程序上花点时间才能让它工作,但这更多的是我自己的失误,而不是你的解释。谢谢你的帮助!