覆盖database.yml的策略?

时间:2010-11-17 13:19:02

标签: ruby-on-rails ruby activerecord yaml

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

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

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

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

执行此操作的一种方法是在我的database.yml中使用Erb:

<%= 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

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

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

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

4 个答案:

答案 0 :(得分:18)

您可以直接在application.rb中提供自己的数据库自定义: 它似乎工作很好的轨道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

答案 1 :(得分:18)

这似乎适用于Rails 3.2.2

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

答案 2 :(得分:14)

这是一个老问题,但是在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

答案 3 :(得分:11)

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

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