覆盖database.yml的策略?

在我的环境中,部署服务器具有database.yml中的大量连接信息。 也就是说,他们知道它们是开发服务器,测试服务器还是生产服务器,并且知道它们各自的数据库连接信息。

我可以将此信息封装在Server类中,以便我可以检索信息:

Server["environment"] #=> production Server["db_host"] #=> db5.example.com Server["db_password"] #=> [a decrypted password] 

等等。 我想部署一个Rails应用程序,并根据服务器设置进行自动配置。 做这个的最好方式是什么?

一种方法是在我的database.yml中使用Erb:

 : adapter: oracle_enhanced host:  username: db_user password:  

我不是太兴奋这样做,但它会工作。 在这种情况下,我将在哪里放置定义Server类的’server.rb’ – 在yml中需要它? 在ActiveRecord加载database.yml之后加载app / initializers。

另一种可能的解决方案是以某种方式覆盖railties的数据库初始化器:

 # File railties/lib/initializer.rb, line 903 def database_configuration require 'erb' YAML::load(ERB.new(IO.read(database_configuration_file)).result) end 

仅在以下情况下调用上述内容:在config.frameworks中定义了active_record。 我不确定如何在Rails启动序列中尽早覆盖这一点。

也许第三个选项是从config.frameworks中删除 :active_record,然后在应用程序初始化程序中创建连接? 我担心这可能会产生很多意想不到的副作用。

希望有一些简单而明显的东西我没有找到,例如ActiveRecordfunction允许我选择退出database.yml并以编程方式提供备用配置。

这里有两个技巧可能会有所帮助。 一个是你所触及的,即修补数据库配置中加载的例程,这当然值得探索。 关于Ruby的好处是你几乎可以修补你不喜欢的东西,并用更好的东西替换它。 这里的责任是,较新版本的Rails可能会使用不同的配置机制,而您的补丁将导致所有内容中断。 也许这是值得付出的代价。

另一种方法是将database.yml文件保留在服务器而不是存储库中,并使用某种部署脚本将其链接到适当的位置。 这种方法的优点是您的版本控制系统中没有重要的密码,您可以更新服务器的配置,而无需修补应用程序。

您可以直接在application.rb中提供自己的数据库自定义:它似乎工作很好的rails 3.2。 (但要注意,这是一种猴子补丁)

 module MyApp class Application < Rails::Application # ... config config.encoding = "utf-8" def config.database_configuration parsed = super raise parsed.to_yaml # Replace this line to add custom connections to the hash from database.yml end end end 

这似乎适用于Rails 3.2.2

 module MyApp class Application < Rails::Application self.paths['config/database'] = 'config/another_db.yml' end end 

这是一个老问题,但是在Rails 4中你可以简单地使用一个环境变量并且有一个空白或缺少database.yml( DATABASE_URL将覆盖任何database.yml)

DATABASE_URL=postgres://myuser:mypass@myposgresbox.com:5432/my-database-name

更多信息: http : //edgeguides.rubyonrails.org/configuring.html#connection-preference