Reputation: 4492
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
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
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
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
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