简体   繁体   中英

Nested form two levels deep in Rails for selecting seeded objects

I am trying to build in a form a nested form going two levels deep . It's about creating a factory. Both the first and the second level are a collection_check_boxes to select seeded objects.

Relations in words

To the first level I had it working and concretely that momentarily looks like:
A factory has many machines , through handles .

Then I wanted to add an association to the machines in the same form:
A machine has many materials , through feeds .

A factory model looks like:

    validates :name, presence: true
    validates :description, presence: true
    # Factory to handle machines. 
    has_many :handles, :dependent => :destroy
    has_many :machines, :through => :handles
    # Factory needs to know about materials (fed through machines).
    accepts_nested_attributes_for :machine

And the machine model is logically derived from this, but without the nested attributes for materials of course. (Materials is an endpoint here.)

Then the controller part for the form to create the factory (factory_controller.rb):

  def factory_params
    params.require(:factory).permit(:name, :description, 
      :machine_ids => [], machines: [:material_ids => [] ])
  end

@materials also exists in the relevant actions.

and the form looks like:

<div class="w3-row">
    <div class="w3-twothird" style="margin-left: 16.65%">

      <%= simple_form_for @factory do |f| %>

        <!-- Input -->
        <%= f.input_field :name %>
        <%= f.label :name %>
        <%= f.error :name %>
        <%= f.input_field :description, rows: 7 %>
        <%= f.label :description %>
        <%= f.error :description %><br><br>

        <div class="w3-row w3-margin-top">
          <!-- Machines card -->
          <div class="w3-third w3-card w3-padding-bottom">
            <h5 class="w3-text-teal w3-center">Machines</h5>
            <ul class="w3-ul" id="machines">
            <%= f.collection_check_boxes :machine_ids, @machines, :id, :name do |b| %>
              <li>
                <%= b.label do %>
                  <%= b.check_box class: "w3-check" %>
                  <%= b.text %>
                <% end %>
              </li>
            <% end %>
            </ul>
          </div>
          <!-- Materials card -->
          <div class="w3-third w3-card w3-padding-bottom">
            <h5 class="w3-text-teal w3-center">Machines</h5>
            <ul class="w3-ul" id="materials">
            <%= f.collection_check_boxes :material_ids, @materials, :id, :sort do |b| %>
              <li>
                <%= b.label do %>
                  <%= b.check_box class: "w3-check" %>
                  <%= b.text %>
                <% end %>
              </li>
            <% end %>
            </ul>
          </div>

        </div>

        <br><br>
        <!-- Zenden -->
        <div class="w3-center w3-margin-bottom">
          <%= f.button :button, class: "w3-btn w3-blue w3-center" %>
        </div>

      <% end %>

  </div>
</div>

Sorry for all the super irrelevant css.

My spec says:

Users can create new factory with associated materials on the associated machines
     Failure/Error: <%= b.check_box class: "w3-check" %>

     ActionView::Template::Error:
       undefined method `material_ids' for #<Factory:0x007fb3f41fbad0>
You should use fields_for method to manage associated fields in a form,

try below code :

<div class="w3-row">
    <div class="w3-twothird" style="margin-left: 16.65%">

      <%= simple_form_for @factory do |f| %>

        <!-- Input -->
        <%= f.input_field :name %>
        <%= f.label :name %>
        <%= f.error :name %>
        <%= f.input_field :description, rows: 7 %>
        <%= f.label :description %>
        <%= f.error :description %><br><br>

        <div class="w3-row w3-margin-top">
          <!-- Machines card -->
          <div class="w3-third w3-card w3-padding-bottom">
            <h5 class="w3-text-teal w3-center">Machines</h5>
            <ul class="w3-ul" id="machines">
            <%= f.collection_check_boxes :machine_ids, @machines, :id, :name do |b| %>
              <li>
                <%= b.label do %>
                  <%= b.check_box class: "w3-check" %>
                  <%= b.text %>
                <% end %>
              </li>
            <% end %>
            </ul>
          </div>
          <!-- Materials card -->
          <% f.fields_for @machines do |ff| %>
            <div class="w3-third w3-card w3-padding-bottom">
              <h5 class="w3-text-teal w3-center">Machines</h5>
              <ul class="w3-ul" id="materials">
              <%= ff.collection_check_boxes :material_ids, @materials, :id, :sort do |b| %>
                <li>
                  <%= b.label do %>
                    <%= b.check_box class: "w3-check" %>
                    <%= b.text %>
                  <% end %>
                </li>
              <% end %>
              </ul>
            </div>
          <% end %>

        </div>

        <br><br>
        <!-- Zenden -->
        <div class="w3-center w3-margin-bottom">
          <%= f.button :button, class: "w3-btn w3-blue w3-center" %>
        </div>

      <% end %>

  </div>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM