Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to populate a select_tag with an array of hashes?

In a Rails 3.2 app I'm trying to add a select field that takes its data from an external API call. This data is returned as an array of hashes:

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

How can I use this data to construct a select field that looks something like:

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

EDIT:

Thanks to the suggestions below I've tried the following:

A:

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

Gives an error:

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

B:

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

Fixes the error but generates the wrong markup

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

So I think my problem is formatting the array of hashes correctly, and I don't know enough about manipulating arrays of hashes to work out how to do this.

Unless I'm looking in completly the worng direction, I think the key to this problem is to reformat the array at the top of this question to give:

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

Is this even possible? And if so, how?

like image 997
Andy Harvey Avatar asked Dec 31 '12 00:12

Andy Harvey


2 Answers

If you have array of hashes like this:

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

You can use options_for_select helper with collect method like this:

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

And its done :-).

like image 84
Nikos Avatar answered Oct 01 '22 19:10

Nikos


A better way to do it in only one command:

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

With your example hash:

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"]]
like image 27
user2503775 Avatar answered Oct 01 '22 19:10

user2503775