Ruby-on-rails 如何使用散列数组填充 select_tag?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14096126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:14:34  来源:igfitidea点击:

How to populate a select_tag with an array of hashes?

ruby-on-rails

提问by Andy Harvey

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:

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

[{"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:

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?

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

采纳答案by user2503775

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

回答by Nikos

If you have array of hashes like this:

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

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

You can use options_for_selecthelper with collectmethod like this:

您可以将options_for_selecthelper 与这样的collect方法一起使用:

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

And its done :-).

它完成了:-)。

回答by Albert Català

The easiest way to use Hashes in selects, for me is:

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

The hash:

哈希:

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

In the form:

在形式:

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

回答by Yves Senn

You can use options_for_selectfor this purpose. It takes a two dimensional Array. You can convert your hash like so:

您可以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)

As a side note to options_from_collection_for_select, it is used in combination with objects. It iterates through the objects and sends a message for the label and one for the id.

作为 的旁注options_from_collection_for_select,它与对象结合使用。它遍历对象并为标签发送一条消息,为 id 发送一条消息。

回答by Andy Harvey

Ok, I eventually figured out a solution that works, though it may not be the best.

好的,我最终想出了一个可行的解决方案,尽管它可能不是最好的。

$ @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"}

I was then able to create a select field

然后我就可以创建一个选择字段

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

that generates the correct markup

生成正确的标记

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

A little convoluted, but its working. I welcome any improvements.

有点复杂,但它的工作原理。我欢迎任何改进。

回答by bonafernando

I'm not really sure why, but none of the answers worked for me. maybe because of Rails 5, so I figured it out by myself and I'm happy to share. It's now pretty but works well.

我不确定为什么,但没有一个答案对我有用。也许是因为 Rails 5,所以我自己弄明白了,我很乐意分享。它现在很漂亮,但效果很好。

It's an Array of Hashes from an external API (Pipedrive) that I want to associate with the user's table:

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

This is in my form:

这是我的形式:

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

And this is in my fake model:

这是在我的假模型中:

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

Hope it helps someone.

希望它可以帮助某人。