Fields_ для отправки массива вместо Hash (Rails 3)

Я использую fields_for в своей форме, например:

<%= form_for @user %>
  ...
  <%= f.fields_for :photos do |f2| %>
    <%= f2.radio_button :public, 'true' %>
  <% end %>
  ...
<% end %>

Вот создаваемые радиокнопки:

<input id="user_photos_attributes_0_public_true" name="user[photos_attributes][0][public]" type="radio" value="true" /> 
<input id="user_photos_attributes_0_id" name="user[photos_attributes][0][id]" type="hidden" value="1" /> 

<input id="user_photos_attributes_1_public_true" name="user[photos_attributes][1][public]" type="radio" value="true" /> 
<input id="user_photos_attributes_1_id" name="user[photos_attributes][1][id]" type="hidden" value="4" /> 

<input id="user_photos_attributes_2_public_true" name="user[photos_attributes][2][public]" type="radio" value="true" /> 
<input id="user_photos_attributes_2_id" name="user[photos_attributes][2][id]" type="hidden" value="5" />
...

У меня это в user.rb

  has_many :photos
  accepts_nested_attributes_for :photos

Когда форма отправлена, я получаю эту ошибку:

Error during failsafe response: ActionView::Template::Error
TypeError (expected Hash (got Array) for param `photos_attributes'):

Кто-нибудь знает, почему это происходит?

Btw, я использую Rails 3.0.0.rc2

Ответ 1

Как вы сохраняете свою модель?

Если вы проверите хеш params, вы получите что-то вроде:

{ :user => {:photo_attributes => [{:id => 1, :public => true}, {:id => 4, :public => false}] }, :your_other_params => ... }}

Итак, a User.new(params[:user]).save должен работать. Если вы не передаете каждый хэш атрибутов вместо массива. См. эту статью, если вам нужна более подробная информация.

Что находится в тэге params? Это поможет вам проследить проблему.

BTW, если вы хотите поведение "истина/ложь" (я предполагаю, что из-за свойства is_public), а не "настоящее/не настоящее", следует использовать флажок. Кнопки радио предназначены для взаимоисключающих опций.

Ответ 2

У меня недавно была та же проблема. Вместо того, чтобы пытаться получить параметры через контроллер, мы использовали инструменты Chrome, чтобы увидеть, что передавалось в параметрах, и обнаружили, что мы проходим пустой хэш/массив, например. params [] по сравнению с параметрами [: something]