Rails: Delete nested form object dynamically

时间:2015-10-30 22:01:52

标签: ruby-on-rails ruby-on-rails-4 nested-forms

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?

2 个答案:

答案 0 :(得分:2)

您应该使用以下内容:

<% 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 %>

这将允许您使用以下内容:

#app/assets/javascripts/application.js
$(".group_goal a.remove").on("click", function(e){
   $(this).parents(".group_goal").remove();
});

你必须记住&#34;动态&#34; fields_for元素只是HTML字段元素,因此可以使用javascript / jquery从DOM中删除。

您正在使用旧Railscast方式实现此目标(那些link_to_add_fields辅助方法已过时。)

实现它的典型方法是使用Cocoon gem,或使用以下答案手动执行:Rails accepts_nested_attributes_for with f.fields_for and AJAX

答案 1 :(得分:-2)

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