2010-11-17 98 views
20

在我的环境中,部署服务器具有很多位于database.yml中的连接信息。也就是说,他们知道他们是开发人员,测试人员还是生产服务器,并且他们知道他们各自的数据库连接信息。重写database.yml的策略?

我可以封装在例如服务器级别的此信息,这样我就可以检索信息:

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

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

一种方法是再培训局我的database.yml:

<%= Server["environment"] %>: 
    adapter: oracle_enhanced 
    host: <%= Server["db_host"] %> 
    username: db_user 
    password: <%= Server["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 

上面被称为仅当:active_record在config.frameworks定义。我不确定我会如何在Rails的启动顺序中尽早覆盖这一点。

也许第三个选项是删除:active_record from config.frameworks,然后在应用程序初始化程序中稍后创建连接?恐怕这可能会带来很多意想不到的副作用。

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

+1

我一个内置的解决方案,希望为虚线。很明显,几年前Rails核心团队就一个补丁提出了一个补丁,该补丁提供了一个替代database.yml的ruby补丁,并得到了一些支持,但它被拒绝了。 http://www.mail-archive.com/[email protected]/msg06694.html – 2010-11-17 13:35:01

+1

注意:从Rails 3.1.2开始,'database_configuration'方法位于'Rails :: Application :: Configuration'中。在以前的版本中,它在'Rails :: Configuration'中。 – 2011-11-21 15:35:03

回答

11

有两个技巧可能有助于这里。一个是你曾经触及过的,那就是将数据库配置中加载的例程进行猴子修补,这当然值得探索。关于Ruby的好处是,你可以修补任何你不喜欢的东西,并用更好的东西代替它。这里的责任是更新版本的Rails可能会使用不同的机制进行配置,并且您的补丁程序将导致一切破坏。也许这是一个值得付出的代价。

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

+0

总是有预初始化程序,您可以使用它来加载服务器类,并使用它从database.yml中。 – 2010-11-17 15:58:36

+0

@François这很有趣。我不知道预初始化程序。谢谢! – 2010-11-17 16:22:22

+0

任何想法,我可以猴子补丁ActiveRecord?在AR加载之后但连接完成之前,我必须这样做。 – 2010-11-17 16:27:51

17

你可以直接在你的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 
+0

正在工作,直到ruby1.9.3,然后我更新到红宝石2.3.x和它的抛出错误说超级不能在NoMethodError上调用:super:没有超类方法'database_configuration'。我会对此提出问题 – carbonr 2016-08-17 07:34:48

17

这似乎在Rails的3.2.2

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

谢谢,这是一种指向另一个database.yml的简单方法。然而在我的情况下,它并没有给我多买东西,因为我不想要硬编码的东西(尤其是生产密码),所以我仍然需要Erb。 – 2012-04-03 18:01:35

+0

就我而言,我为不同的环境设置了不同的.yml。我仍然喜欢在文件中配置文件,其中一些文件可能位于我的源代码库(即使用sqlite3进行开发),但是在服务器上手动配置生产。 – aceofspades 2012-04-03 21:53:59

+0

谢谢。在application.rb中添加'self.paths ['config/database'] ='config/another_db.yml'在Rails3中有效。 – 2012-08-07 20:30:52