How to use fields_for for child update in 1-to-many in rails 3.1.3?

A user has many user_levels and a user_level belongs to a user. We are
having difficulty updating the user_level. Here is the code for
user_level update:

    <%= simple_form_for @user do |f| %>
      <% @user.user_levels.each do |level| %>
        <%= f.fields_for :user_levels, level, :index => level do |
builder> %>
          <p><%= render :partial => 'user_levels', :locals => {:f =>
builder, :i_id => level.position} %></p>
        <% end %>
      <% end %>
    <% end %>

The code above will display the current user_level with selected set
to the current position. But the update was not saved for user_level.

Here is the user_levels partial

    <div class="fields">
      <%= f.input :position, :collection => return_position, :prompt
=> "Choose position",
                          :label => false, :include_blank =>
true, :selected => i_id %>
      <%= link_to_remove_fields "remove", f %>
    </div>

Here is the string posted to the server for params[:user]. There are
currently two positions for the user and one gets deleted as update:

    {"name"=>"test eng", "login"=>"tester12", "password"=>"password",
"password_confirmation"=>"password", "user_type"=>"employee",
"user_levels_attributes"=>{"0"=>{"id"=>"5"},
"1"=>{"position"=>"elec_eng", "_destroy"=>"false", "id"=>"6"}}}

The app has no problem creating a new user with multiple user_levels.

Any solution for child update? Thanks so much

I recommend you visit Ryan Bates site RailsCasts.com and watch
episodes 196 and 197.
You should go ahead and subscribe, so he will keep doing stuff like
this.

Cheers!
SC

A user has many user_levels and a user_level belongs to a user. We are

having difficulty updating the user_level. Here is the code for

user_level update:

<%= simple_form_for @user do |f| %>

  <% @user.user_levels.each do |level| %>

    <%= f.fields_for :user_levels, level, :index => level do |

builder> %>

      <p><%= render :partial => 'user_levels', :locals => {:f =>

builder, :i_id => level.position} %>

    <% end %>

  <% end %>

<% end %>

The code above will display the current user_level with selected set

to the current position. But the update was not saved for user_level.

Here is the user_levels partial

<div class="fields">

  <%= f.input :position, :collection => return_position, :prompt

=> “Choose position”,

                      :label => false, :include_blank =>

true, :selected => i_id %>

  <%= link_to_remove_fields "remove", f %>

</div>

Here is the string posted to the server for params[:user]. There are

currently two positions for the user and one gets deleted as update:

{"name"=>"test eng", "login"=>"tester12", "password"=>"password",

“password_confirmation”=>“password”, “user_type”=>“employee”,

“user_levels_attributes”=>{“0”=>{“id”=>“5”},

“1”=>{“position”=>“elec_eng”, “_destroy”=>“false”, “id”=>“6”}}}

The app has no problem creating a new user with multiple user_levels.

Any solution for child update? Thanks so much

Strange. The params hash seems correct (I did some similar tests in my
app). If I understand correctly, this should do:

  • leave the user_level with id 5 untouched

  • update the position of user_level with id 6 (if it was changed)

The “_destroy”=>“false” should not matter

Which one of the two user_levels gets deleted (with id 5 or id 6).

If you puts the user.user_levels (in the controller) just before the

update_attributes line, like below, you can make sure the user_levels
are still there just before.

def update

add this to debug the status just before the update_attributes

puts user.user_levels.inspect

user.update_attributes(params[:user])

end

Also, you could try the update_attributes action in the rails console
to isolate the problem.

user = User.find …
user.user_levels

h = {“name”=>“test eng”, “login”=>“tester12”, “password”=>“password”,

“password_confirmation”=>“password”, “user_type”=>“employee”,

“user_levels_attributes”=>{“0”=>{“id”=>“5”},

“1”=>{“position”=>“elec_eng”, “_destroy”=>“false”, “id”=>“6”}}}

user.update_attributes(h)
user.user_levels

That is how tested the expected behavior (of course with different model

names for my app).

HTH,

Peter