2011-08-16 39 views
54

我加載在Rails的3.0.9 YAML文件中這樣加載YAML哈希並參考:滑軌由符號

APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__))) 

它加載的所有像分層哈希,沒有問題的內容。我不喜歡的部分是隻能用單引號或雙引號訪問哈希,而不能使用符號。

APP_CONFIG['mailer']['username'] # works fine 
APP_CONFIG[:mailer][:username] # doesn't 

有什麼想法?使用

回答

71

嘗試HashWithIndifferentAccess

APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))) 
+0

感謝百萬Rob。唯一的竅門是確保Rails已經加載。 –

+2

看起來不錯,但我不使用ActiveSupport –

+0

<3謝謝你的男人! –

2

你可能習慣在Rails的params哈希表,這實際上是一個HashWithIndifferentAccess,而不是一個標準的Ruby Hash對象。這允許你使用'action'之類的字符串或者像'action'這樣的符號來訪問內容。

使用HashWithIndifferentAccess,無論使用什麼,您都會得到相同的結果,但請記住,這隻適用於HashWithIndifferentAccess對象。

因此,爲了使與YAML這項工作,你必須YAML.load的結果加載到HashWithIndifferentAccess,像這樣:

APP_CONFIG = HashWithIndifferentAccess.new( YAML.load(File.read(File.expand_path('../app.yml', __FILE__))) ) 
+0

不錯的信息@Tilo(y) –

9

有,而周圍挖我發現了另一個潛在的答案。

您可以通過,而不是添加給你的YAML文件的頂部放棄HashWithIndifferentAccess.new:

--- !map:HashWithIndifferentAccess 

然後只需YAML.load正常人一樣。唯一的技巧就是如果你在你的環境中使用初始化工具等(如我)那樣需要加載rails。

28

另一種解決方案是將您想要訪問的鍵作爲帶冒號的符號進行訪問。例如:

default: &default 
    :symbol: "Accessed via a symbol only" 
    string: "Accessed via a string only" 

development: 
    <<: *default 

test: 
    <<: *default 

production: 
    <<: *default 

以後你就可以訪問這些像這樣:

APP_CONFIG[:symbol] 
APP_CONFIG['string'] 

請注意,我用的YAML::ENGINE.yamler = "syck"。不知道這是否適用於psych。使用它創建重複鍵的副作用::(精極度緊張肯定不會支持關鍵的合併,因爲我的例子顯示,雖然)。

關於使用HashWithIndifferentAccess一個符號連接和一個字符串的訪問。如果您將YAML數據作爲數組傳遞,這可能是邪惡的。如果您使用該解決方案,請注意這一點。

+0

這就是我需要的,謝謝! –

+0

這應該是真正的答案。對於任何人來說,YAML屬性在默認情況下都不會被解析爲符號。 –

23

如果您正在Ruby on Rails中工作,您可能需要查看symbolize_keys(),這正是OP所要求的。如果散列很深,可以使用deep_symbolize_keys()。使用這種方法,得到的答案是

APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__))).deep_symbolize_keys 
+0

這不適用於嵌套屬性 –

+6

'deep_symbolize_keys()'應處理嵌套屬性。 – streetlogics

+0

好的解決方案,但它是ActiveSupport的一部分。但它在使用Rails的情況下工作 –

12

這是從選定的答案相同,但有一個更好的語法:

YAML.load(File.read(file_path)).with_indifferent_access 
7
  1. Rails有象徵鍵的特殊方法。
  2. 您可以使用load_file方法並擺脫File.read
  3. 不確定您是否還需要expand_path,默認目錄是rails root。

我會寫這麼簡單:

YAML::load_file('app.yml').symbolize_keys