Хэш, добавленный в модель, нельзя использовать в качестве поля для помощника по тегу формы Select - PullRequest
2 голосов
/ 05 июня 2011

Я добавил хеш к модели (заполняемой из ассоциации многие-многие) и хотел бы создать в представлении выборки, которые можно использовать для изменения ассоциаций.Единственная проблема, с которой я столкнулся, заключается в самом представлении, где я хотел бы использовать такую ​​конструкцию, как:

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

, она работает отлично.Я делаю что-то не так, пытаясь использовать помощник по тегу формы выбора, или это просто ограничение помощника?

1 Ответ

0 голосов
/ 07 июня 2011

К сожалению, вы не сможете использовать помощник по формам #select для доступа к хешу, определенному в вашей модели. Хелпер формы #select в конечном итоге (если вы следите за ним обратно) вызывает #options_from_collection_for_select helper. Этот код ниже.

Как вы можете видеть, то, что вы передаете как "метод" (второй параметр) помощнику формы #select, становится value_method во втором вызове и, в конечном счете, вызывается для получающего объекта через вызов метода #send. Итак, что происходит, ruby ​​пытается сделать это:

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

... таким образом, неопределенная ошибка метода. Я не знаю, как передать дополнительные параметры, которые вам понадобятся для извлечения соответствующего значения из вашего хэша при использовании помощника #select, хотя метод #send позволяет отправлять дополнительные параметры.

Вы могли бы, вероятно, выполнить то, что вам нужно, с помощью некоторого хакерского переопределения method_missing, но, как вы сказали, другой случай, использующий options_for_select, работает. Вместо отдельных вызовов #tag и #options_for_select могу я предложить вам использовать # select_tag , который ожидает вывод из #options_for_select во втором параметре

  # 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...