Reputation: 4320
I have a form for add nested objects, like this:
This is the principal form:
#purchasing_goals.html.erb
<%= f.fields_for :group_goals do |builder| %>
<%= render partial: 'group_goal_fields', locals: { f: builder } %>
<% end %>
<div>
<%= link_to_add_fields("Add", f, :group_goals) %>
</div>
and this is the nested form:
<div class="group-goal">
<%= f.text_field :num_of_users, label: "No. Usuarios" %>
<%= f.text_field :discount_percentage, label: "Descuento" %>
<%= f.hidden_field(:_destroy) %>
<%= link_to_remove_fields("Delete", f, "'.group-goal'") %>
</div>
and these are the helpers for add and remove group_goals items:
def link_to_remove_fields(name, f, removal_class)
link_to name, "javascript:void(0);", onclick: "remove_fields(this, #{removal_class})"
end
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to(name, "javascript:void(0);", onclick: "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
end
It works great, it adds a new item when you click the "Add" button, however when I click the "Delete" button it deletes the item in the form but not in the params of the form, so when I click the submit button an empty nested object is sent to the controller, How can I make the delete button delete the item not only in the form (visually) but also delete the created object?
Upvotes: 2
Views: 3662
Reputation: 76774
You should use the following:
<% content_tag :div, class: "group-goal", id: f.options[:child_index] do %>
<%= f.text_field :num_of_users, label: "No. Usuarios" %>
<%= f.text_field :discount_percentage, label: "Descuento" %>
<%= f.hidden_field(:_destroy) %>
<%= link_to "Remove", "#", class: "remove", %>
<% end %>
This will allow you to use the following:
#app/assets/javascripts/application.js
$(".group_goal a.remove").on("click", function(e){
$(this).parents(".group_goal").remove();
});
You must remember that "dynamic" fields_for
elements are simply HTML field elements, and thus can be removed from the DOM with javascript/jquery.
You're using the old Railscast way of achieving this (those link_to_add_fields
helper methods are outdated).
The typical way to achieve it is to use the Cocoon
gem, or to do it manually using answers like this: Rails accepts_nested_attributes_for with f.fields_for and AJAX
Upvotes: 3
Reputation: 5105
I guest you have to ensure several steps to fix it.
Check your strong parameter in your controller and add _destroy
and id
def hotel_params
params.require(:purchasing_goal).permit(:your_own_field, group_goals_attributes: [ :id, :num_of_users, :discount_percentage, :_destroy ])
end
Next, check your purchasing_goal.rb
model to add allow_destroy: true
accepts_nested_attributes_for :group_goals,
reject_if: proc { |attributes| attributes['num_of_users'].blank? },
allow_destroy: true
I hope this help you. For more information nested_forms-rails-4.2
Upvotes: -1