brewster
brewster

Reputation: 4492

nested form & update_attributes

i am having trouble updating data in a multi-level nested form. i use partials to include all the fields for both the create & update views, and i do NOT have a problem with creating. only with updating.

essentially the structure (simplified) is:

user has_one profile
profile has_many addresses

form_for @user do |u|
  u.fields_for :profile do |p|
    p.fields_for :addresses do |a|

like i said, creating the user, profile, and addresses works fine. only until i attempt to update do i find problems. i don't receive an error, it actually shows it was successfully updated. and it actually does properly update the user & profile fields, just not the address fields.

here are the params for the update from the stack trace. (again, summarized & formatted)

Parameters: {"controller"=>"profiles", "action"=>"update", "_method"=>"put", "id"=>"1", 
  "user"=>{"login" => "username",
    "profile_attributes"=>{"first_name"=>"Admin",
      "addresses_attributes"=>{
        "0"=>{"address"=>"123 Address Ave.", "city"=>"Cityville", "state"=>"CA"}
      }
    }
  }
}

all of the documentation i can find only shows 1 nested form, so i am not sure if i am using update_attributes properly for more than 1 level deep.

any thoughts?

Upvotes: 4

Views: 4026

Answers (4)

Leopoldo Silva
Leopoldo Silva

Reputation: 11

I was also having the same problem at updating, not at creating. My class model is Lecture has_many widgets

class Lecture < ActiveRecord::Base
  attr_accessible :name , :order , :html, :widgets_attributes 
  has_many :widgets
  accepts_nested_attributes_for :widgets,  :allow_destroy => true
end

class Widget < ActiveRecord::Base
    belongs_to :lecture
    attr_accessible :width, :height, :xpos, :ypos, :source
end

The last line of the Widget class made all the difference.

Upvotes: 1

Fran&#231;ois
Fran&#231;ois

Reputation: 987

I ran into a similar problem. In my case it was because of a "reject_if" clause in the accept_nested_attributes_for class method.

accepts_nested_attributes_for :player, :reject_if => proc { |attributes| attributes['full_name'].blank? }

By leaving an empty string in the player "full_name" attribute, Rails will not even try to update the attributes present in the nested form. In my case I realized I didn't need the reject_if clause so I fixed the problem by removing it.

Upvotes: 4

nathanvda
nathanvda

Reputation: 50057

i created a gem called cocoon which can help you with that. It works with standard Rails forms, formtastic or simple-form.

The gem works with multiple nested levels. The readme on github should you get you started fairly easily. If you need more help, let me know.

Upvotes: 1

Gareth
Gareth

Reputation: 138042

Are you using attr_accessible anywhere in your model, to whitelist the fields that are allowed for mass assignment? If so, then you'll also need to add

attr_accessible :address_attributes

to allow those attributes to be passed to update_attributes.

If you aren't already using attr_accessible (or it's not-recommended sister attr_protected) then don't add this line as it'll stop all of your ther attributes being saved.

Upvotes: 6

Related Questions