Rails: 动态删除嵌套的表单对象

Rails: Delete nested form object dynamically

我有一个用于添加嵌套对象的表单,如下所示:

这是主要形式:

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

这是嵌套形式:

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

这些是添加和删除 group_goals 项的助手:

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

效果很好,当您单击 "Add" 按钮时,它会添加一个新项目,但是当我单击 "Delete" 按钮时,它会删除表单中的项目,但不会删除表单,所以当我点击提交按钮时,一个空的嵌套对象被发送到控制器,我怎样才能让删除按钮不仅删除表单中的项目(视觉上)而且删除创建的对象?

我想你必须确保几个步骤来修复它。 检查控制器中的强参数并添加 _destroyid

def hotel_params
  params.require(:purchasing_goal).permit(:your_own_field, group_goals_attributes: [ :id, :num_of_users, :discount_percentage, :_destroy ])
end

接下来,检查您的 purchasing_goal.rb 模型以添加 allow_destroy: true

accepts_nested_attributes_for :group_goals,
                                reject_if: proc { |attributes| attributes['num_of_users'].blank? },
                                allow_destroy: true

希望对您有所帮助。欲了解更多信息 nested_forms-rails-4.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();
});

您必须记住 "dynamic" fields_for 元素只是 HTML 字段元素,因此可以使用 javascript/jquery 从 DOM 中删除。


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

实现它的典型方法是使用 Cocoon gem, or to do it manually using answers like this: Rails accepts_nested_attributes_for with f.fields_for and AJAX