Rails problem accepts_nested_attributes_for
I have this problem:
My web application has a form where the users can customize their profile. In each profile can be specified many skills and I want to allow the users to press one button (add new skill) in order to specify as many skills as they want. So this is the controller code:
accepts_nested_attributes_for :skills, :allow_destroy=>true, :reject_if => lambda {|a| a[:name].blank?}
This is the form (just the part with the nested attribute skill):
<%= f.fields_for :skills do |builder|%>
<div class="field">
<%= builder.label 开发者_Python百科:skill %>
<%= builder.text_field :name%>
<%= builder.hidden_field :_destroy %>
<%= link_to 'remove', '#', :onclick=>'removeField()'%>
</div>
<%end%>
This form work perfectly and shows each skill of the user, it allows editing etc. The problem now, is that I want to add a link to "add new skill" so a javascript function that change the form and add new skill input field, I really have no idea to how to act, mainly because the nested attributes have specific id and name in the form that I don't understand:
<input id="profile_skills_attributes_0_name" name="profile[skills_attributes][0][name]" size="30" type="text" value="Mathematicansszz" />
It also add another hidden input field with the id of the skill (impossible to predict if the skill is not created), make impossible to create new skill from an HTML static pages?
<input id="profile_skills_attributes_0_id" name="profile[skills_attributes][0][id]" type="hidden" value="3" />
Any idea or workaround ? Thank you
I have written a gem that can handle that makes handling nested forms dynamically easier: cocoon. The gem works with the standard rails formhelpers, but also with formtastic or simple_form.
I would also advise you to checkout formtastic or simple_form, as those are awesome gems to make form-handling easier. But as with HAML, that is a personal choice.
fields_for creates an array of fields. The "0" in the name represents the index in the array. Since you're creating new records you can simply ignore the hidden id field.
So via javascript you just need to do two things: 1. Count the number of existing inputs for the child collection in order to get a new index. 2. Add a new text field using the new index.
This is relatively easy to do with jQuery using a wildcard selector like $('input[name$="][name]"]').length; to retrieve a count (for the new index). If you have another field for array with name fields you may want to use a regex selector instead (via plugin). An easier way might be to just add a class to each of your skill name inputs and use that class as the selector when counting.
To append the new input see:
http://api.jquery.com/append/
If you're not using jquery, then it should be similar in other frameworks with a little googling.
精彩评论