2011-03-31 32 views
3

說我有我的鐵軌配置的YML文件...導軌:陽明合併

settings.yml中

defaults: &defaults 
    interceptor_email: [email protected] 

development: 
    <<: *defaults 

test: 
    <<: *defaults 

production: 
    <<: *defaults 

,我想有沒有包含在另一個版本的文件陽明海運每個開發人員在本地維護控制...

user_settings.yml

development: 
    interceptor_email: [email protected] 

如何合併這些鍵?我正在用esb處理我的yml文件,所以這也是一個選項。只是無法弄清楚如何去做。如果我的環境中缺少密鑰,我將它設置爲使密鑰回退到默認值。

+0

另請參見[** Snappconfig **](https://github.com/ ykessler/snappconfig)gem – Yarin 2013-09-24 10:56:16

回答

4

你不能分別讀取兩個yml文件嗎?

settings = YAML.load(path_to_settings)[RAILS_ENV].symbolize_keys 
user_settings = YAML.load(path_to_user_settings)[RAILS_ENV].symbolize_keys 
settings.merge!(user_settings) 

現在你應該有設置的散列值,那麼你可以合併散列,如果你想。如果第二個散列與第一個散列具有相同的密鑰,則第一個散列將被覆蓋。

+0

問題是,當這些定義在'locale.yml'中時,你無法真正合並文件,因爲沒有任何合併。 – firedev 2013-01-22 11:45:58

+0

'deep_merge'會阻止後者覆蓋前者,因此如果設置具有development.unique_variable,則user_settings將不會取消它,因爲它的開發集合不包含它。 – dave 2017-09-18 04:35:39

1

這是我要做的事(聲明,我只是寫了,所以它沒有單元測試還沒有等...因爲我改進它,我會更新這個):

require 'yaml' 

# read config files (currently only yaml supported), merge user config files over 
# defaults and make the parsed data available to the rest of your application. 
# 
module YourNamespace class Config 

    attr_reader :files, :get 


    # Accepts a string filename or an array of string filenames to parse. 
    # If an array is supplied, values from later files will override values 
    # of earlier files with the same name. 
    # Will choke if YAML.load_file returns false (invalid or empty file) 

    # 
    def initialize(files) 

     @files = files.respond_to?('map') ? files : [ files ] 

     @get = @files            \ 
                    \ 
     .map { | file | YAML.load_file file }     \ 
     .reduce({}, :merge!) 

     ; 

    end 

end end 

你可以這樣稱呼它:

config = YourNamespace::Config.new 'config.yml' 

# or have the second one override the first 
# 
config = YourNamespace::Config.new [ 'config-defaults.yml', 'config.yml' ] 

如果你想去看看,這裏有很多改進的餘地。理想的做法是將'Config'作爲一個不涉及文件的界面,並且在YamlConfig,IniConfig,CliConfig,DbConfig,CookieConfig中實現。這樣,如果你決定有一天那個新的配置格式超級播種yaml是如此酷,你可以很容易地改變它,而不會破壞任何東西。你可以讓命令行配置選項輕鬆地覆蓋來自配置文件的配置選項。而且,無論配置值來自哪裏,您都可以爲任何ruby項目重新使用配置模塊。或者,也許只是停止inventing hot water。快速瀏覽讓我覺得那裏有一些相當熱水...

接下來編寫一些文檔,單元測試,輸入驗證,錯誤處理併爲配置值創建一些花哨的讀/寫訪問器。也許你希望能夠請求這樣的配置值,而不是一直寫數組和哈希:

config.get 'app.component.section.setting' 

# or this if you want to keep them separate: 
# 
config.get('app', 'component', 'section', 'setting') 
+0

這是一個很好的答案,可能是原版海報的用例太過分了,但是可以通過下面的方法來減少:合併似乎是一個很好的方法來平滑哈希數組。 – 2015-05-27 23:05:34