1

我已经用 Cocoon 和表格成功地实现了一级嵌套表单。但是,我很难将注意力集中在如何做另一个嵌套级别上。我的问题是如何用桌子做到这一点。也许一张桌子根本不是写的方式。谢谢你帮助一个新手。

这是我的模型:

class Profession < ApplicationRecord
  has_many :procedure_categories, dependent: :destroy
  accepts_nested_attributes_for :procedure_categories, allow_destroy: true
end

和:

class ProcedureCategory < ApplicationRecord
  belongs_to :profession
  has_many :procedures

  accepts_nested_attributes_for :procedures, allow_destroy: true
end

和:

class Procedure < ApplicationRecord
  belongs_to :procedure_category
end

这是我的顶级表单代码:

<%= form_for(@profession) do |f| %>
  <%= render 'shared/profession_error_messages' %>

  <%= f.label :profession %>
  <%= f.text_field :profession, class: 'form-control'  %>

  <%= f.label :description %>
  <%= f.text_field :description, class: 'form-control'  %>

  <%= f.label :active, class: "checkbox inline" do %>
    <%= f.check_box :active %>
    <span>Active profession?</span>
  <% end %>

  <table class='table'>
    <thead>
      <tr>
        <th>Category</th>
        <th>Description</th>
        <th>Display Order</th>
        <th>Selection Type</th>
        <th>Delete</th>
        <th>Edit</th>
      </tr>
    </thead>
    <tbody class="categories">
      <%= f.fields_for :procedure_categories do |procedure_category| %>
        <%= render 'procedure_category_fields', f: procedure_category %>
      <% end %>
    </tbody>
  </table>


  <%= link_to_add_association 'Add Category', f, :procedure_categories, 
    data: { association_insertion_node: '.categories', association_insertion_method: :append } %>

  <br><br>    
  <%= f.submit "Save", class: "btn btn-primary" %>
  <% end %>

下一个部分向下一级:

<tr class="nested-fields">
  <td><%= f.text_field :category, class: 'form-control' %></td>
  <td><%= f.text_field :description, class: 'form-control' %></td>
  <td><%= f.text_field :display_order, class: 'form-control' %></td>
    <% cs = options_for_select(controls, f.object.selection_type) %>
  <td><%= f.select :selection_type, cs, class: 'form-control' %></td>
  <td><%= link_to_remove_association "Remove Category", f %></td>
  <% if f.object != nil %>
    <td><%= link_to "Category", edit_procedure_category_path(@profession,f.object) %><td></td>
  <% end %>
</tr>

所以,我正在努力解决如何实现嵌套的最终级别(程序)。

谢谢你的聆听。

4

1 回答 1

1

利用has_many :through

这是我的模型:

class Profession < ApplicationRecord
  has_many :procedures, through: categories
  has_many :categories, dependent: :destroy
  accepts_nested_attributes_for :categories, allow_destroy: true
end

将此procedure_category模型重命名为category

class Category < ApplicationRecord
  belongs_to :profession
  has_many :procedures

  accepts_nested_attributes_for :procedures, allow_destroy: true
end

和:

class Procedure < ApplicationRecord
  belongs_to :category
end

如果我错过了什么,您可以查看rails guide 中的说明

控制器professions#new操作应创建以下变量,以便它们在视图中可用:

def new
    @profession = Profession.new
    @categories = @profession.categories.build
    @procedures = @categories.procedures.build
end

视图使用该变量,因此存储用户输入并使用存储在哈希中的这些输入post发出请求/profession/parameters

<%= form_for(@profession) do |f| %>
      <%= f.fields_for :categories do |category| %>
               <%= category.fields_for :procedures do |precedure| %>
               <% end %>
      <% end %>
<% end %>

fields_for 产生一个表单构建器。参数的名称将是 accept_nested_attributes_for 所期望的。例如,当创建一个有 2 个地址的用户时,提交的参数如下所示:

这就是你的parameters样子:

{
  'profession' => {
    'name' => 'John Doe',
    'categories_attributes' => {
      '0' => {
        'kind' => 'Home',
        'street' => '221b Baker Street',
        'procedures_attributes' => {
         '0' => {},
         '1' => {}
         }
      },
      '1' => {
        'kind' => 'Office',
        'street' => '31 Spooner Street'
      }
    }
  }
}

所以请确保您的表单指向posturl/professions/并且路由将触发professions#create操作

def create
    binding.pry
end

对于任何问题,请设置 abinding pry并在控制台中检查您parameters的显示方式。

在http://guides.rubyonrails.org/form_helpers.html#building-complex-forms了解更多信息

于 2017-11-10T13:41:17.657 回答