如何使用哈希数组填充select_tag?

时间:2012-12-31 00:20:34

标签: ruby-on-rails

在Rails 3.2应用程序中,我正在尝试添加一个从外部API调用获取其数据的选择字段。此数据作为哈希数组返回:

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

如何使用此数据构建类似于以下内容的选择字段:

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

编辑:

感谢下面的建议,我尝试了以下内容:

A:

<%= 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"}

这甚至可能吗?如果是这样,怎么样?

6 个答案:

答案 0 :(得分:38)

如果你有这样的哈希数组:

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

您可以options_for_select使用collect方法使用{{3}}方法:

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

完成了: - )。

答案 1 :(得分:11)

只在一个命令中执行此操作的更好方法:

<%= 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"]]

答案 2 :(得分:2)

对我来说,选择哈希的最简单方法是:

哈希:

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

表格形式:

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

答案 3 :(得分: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的旁注,它与对象结合使用。它遍历对象并发送标签的消息和id的消息。

答案 4 :(得分: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>

有点费解,但它的工作。我欢迎任何改进。

答案 5 :(得分:0)

我不确定为什么,但没有一个答案对我有用。也许是因为Rails 5,所以我自己想出来,我很乐意分享。 它现在很漂亮,但运作良好。

这是一个来自外部API(Pipedrive)的哈希数组,我想与用户的表关联:

这是我的形式:

<%= form.collection_select(:id_user_pipedrive, Owner.all_id_name, :id, :name, :include_blank => '') %>

这是我的假模型:

UserPipedrive = Struct.new(:id, :name)
def self.all_id_name
  all["data"].map { |d| UserPipedrive.new(d["id"],d["name"]) }
end

希望它有所帮助。

相关问题