Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fields_for sending array instead of Hash (Rails 3)

I'm using fields_for in my form like so

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

Here are the radio buttons it generates:

<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" />
...

I have this in user.rb

  has_many :photos
  accepts_nested_attributes_for :photos

When form is submitted I get this error:

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

Does anyone know why this is happening?

Btw, I'm using Rails 3.0.0.rc2

like image 989
Brian Armstrong Avatar asked Aug 26 '10 04:08

Brian Armstrong


2 Answers

How are you saving your model?

If you inspect the params hash, you will get something like:

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

So a User.new(params[:user]).save should work. Unless you are passing each hash of attributes instead of the array. See this article if you need a more in-depth detail.

What is in your params hash? That'd help you to trace the problem.

BTW, if you want a "true/false" behavior (I assume that because of the is_public property), rather than "present/non-present", a checkbox should be used. Radio buttons are for mutually exclusive options.

like image 126
Chubas Avatar answered Nov 03 '22 07:11

Chubas


I recently had the same problem. Instead of trying to get the params through the controller, we used the Chrome tools to see what was being passed in the params and found that we were passing an empty hash/array e.g. params[] versus params[:something]

like image 28
Waley Chen Avatar answered Nov 03 '22 07:11

Waley Chen