添加到模型中的哈希不能用作Select表单标记帮助程序的字段

时间:2011-06-04 22:30:54

标签: ruby-on-rails forms select hash

我已经为模型添加了一个哈希(从多对多关联中填充),并希望在视图中创建可用于更改关联的选择。我唯一的问题是在视图本身,我想使用如下构造:

<% categories.each do |category| %>
  <%= select :location, "group_hash[category.id]", category.enumerate_paths) %>
<% end %>

ROR在“group_hash [category.id]”上窒息,并显示错误消息:

undefined method `group_hash[category.id]' for #<Location:0x107fa2aa0>

即使已定义。当我使用以下代码手动构建构造时:

<%= tag "select", {:id => "location_group_hash_#{category.id}",
                 :name => "location[group_hash[#{category.id}]]" }%>
<%= options_for_select category.enumerate_paths, 
                     @location.group_hash[category.id] %>

它完美无缺。我在尝试使用select form tag helper时做错了什么,或者这仅仅是帮助者的限制?

1 个答案:

答案 0 :(得分:0)

不幸的是,您将无法使用#select表单帮助程序来访问模型中定义的哈希值。最终#select表单助手(如果你跟着它)调用#options_from_collection_for_select助手。该代码如下。

正如您所看到的,作为“方法”(第二个parm)传递给#select表单助手的内容在第二个调用中变为value_method,并最终通过#send方法调用在接收对象上调用。那么,ruby会尝试这样做:

@location.send("group_hash[category.id]")

...因此未定义的方法错误。我不知道在使用#select帮助程序时传递你需要从哈希中提取适当值的其他参数的任何方法,尽管#send方法允许发送其他参数。

你可以想象用一些hackish method_missing覆盖来完成你所追求的东西,但正如你所说,使用options_for_select的另一种情况是有效的。我可以建议您使用 #select_tag ,而不是单独的#tag和#options_for_select调用,这需要#options_for_select在其第二个parm中的输出

  # File actionpack/lib/action_view/helpers/form_options_helper.rb, line 339
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
  options = collection.map do |element|
    [element.send(text_method), element.send(value_method)]
  end
  selected, disabled = extract_selected_and_disabled(selected)
  select_deselect = {}
  select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected)
  select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled)

  options_for_select(options, select_deselect)
end