我已经为模型添加了一个哈希(从多对多关联中填充),并希望在视图中创建可用于更改关联的选择。我唯一的问题是在视图本身,我想使用如下构造:
<% 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时做错了什么,或者这仅仅是帮助者的限制?
答案 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