2012-12-31 50 views
15

在Rails 3.2應用程序中,我試圖添加一個從外部API調用中獲取數據的選擇字段。這些數據返回哈希的數組:如何使用散列數組填充select_tag?

[{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 

如何使用這些數據來構建一個選擇欄,看起來像:

<select> 
    <option value="001"> NameA </option> 
    <option value="002"> NameB </option> 
</select> 

編輯:

感謝的建議下面我已經試過如下:

答:

<%= select_tag 'model[field]', options_from_collection_for_select(@hash, :id, :name) %> 

給出了一個錯誤:

undefined method `name' for {"name"=>"NameA", "id"=>"001"}:Hash 

B:

<%= select_tag 'model[field]', options_from_collection_for_select(@hash) %> 

修正錯誤,但產生了錯誤的標記

<option value="{"name"=>"NameA", "id"=>"001"}"> {"name"=>"NameA", "id"=>"001"}</option> 

所以我覺得我的問題是正確格式化哈希數組,並且我不知道如何操作哈希數組以解決如何執行此操作。

除非我期待在完全地將撥錯方向,我認爲關鍵這個問題是重新格式化陣列在這個問題上給:

{"NameA" =>"001", "NameB" =>"002"} 

這甚至可能嗎?如果是這樣,怎麼樣?

+0

也許會有幫助嗎? – jxpx777

+0

謝謝@ jxpx777,我已經看過這個。如果我使用這個解決方案,我會得到'未定義的方法'last''。我認爲我的問題在於其他地方 –

+0

啊,因爲它是一個哈希,參數是調用select和select的值的方法。嘗試options_for_select with @ hash.to_a http://apidock.com/rails/v3.2.8/ActionView/Helpers/FormOptionsHelper/options_for_select – jxpx777

回答

7

一個更好的辦法來做到這一點的只有一個命令:

<%= select_tag "model[field]", options_for_select(@array_of_hashes.map { |obj| [obj['name'], obj['id']] }) %> 

你的榜樣哈希:

irb> @array_of_hashes = [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 
=> [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 
irb> @array_of_hashes.map { |obj| [obj['name'], obj['id']] } 
=> [["NameA", "001"], ["NameB", "002"]] 
1

您可以使用options_for_select來實現此目的。它需要一個二維數組。你可以把你的哈希像這樣:

data = [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 
data_for_select = data.each { |hash| [hash['name'], hash['id']] } 
options_for_select(data_for_select) 

作爲一個側面說明,以options_from_collection_for_select,它與物體的組合使用。它遍歷對象併爲標籤發送消息,爲標識發送消息。

+0

感謝@Yves,'data_for_select'行對散列沒有任何影響。任何其他想法? –

0

好吧,我最終想出了一個可行的解決方案,雖然它可能不是最好的。

$ @array_of_hashes = [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 
=> [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 
$ @formatted_array_of_hashes = @array_of_hashes.each.map{ |h| { h["name"] => h["id"] }} 
=> [{"NameA" => "001"}, {"NameB" => "002"}] 
$ @merged_hash = Hash[*@formatted_array_of_hashes.map(&:to_a).flatten] 
=> {"NameA" => "001", "NameB" => "002"} 

當時我能夠創建一個選擇欄

<%= select_tag 'model[field]', options_for_select(@merged_hash) %> 

產生正確的標記

<select> 
    <option value="001">NameA</option> 
    <option value="002">NameB</option> 
</select> 

有點令人費解,但其工作。我歡迎任何改進。

+0

當你看到我的答案時,改變你的代碼,你做的事情很長而且沒有必要! – user2503775

35

如果您有散列的數組是這樣的:

@people = [{"name"=>"NameA", "id"=>"001"}, {"name"=>"NameB", "id"=>"002"}] 

您可以使用options_for_select幫手collect這樣的方法:

= select_tag "people", options_for_select(@people.collect {|p| [ p['name'], p['id'] ] }) 

其完成:-)。

+1

Yeap ...好,很短,工作很棒...Ευχαριστώ。 –

+0

謝謝尼科斯,你可以請包括一個鏈接todocumentation。會非常有幫助,謝謝 –

1

在選擇使用哈希最簡單的方式,對我來說是:

散列:

REVISION_TYPES={"S"=>"Stock", "T"=>"Traducción"} 

在形式:

select_tag(:revision_type,options_for_select(REVISION_TYPES.invert.to_a)) 
+0

感謝@albert,但問題是關於一組哈希 –