2010-11-17 75 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