ruby-on-railsrubyreform

Nested property fields do not show up using the Reform gem


I'm using the Reform gem to make a form object in my current project but the nested fields don't show up in the form. Here's my code:

Shipment Model:

class Shipment < ApplicationRecord
  has_one :shipment_detail
end

ShipmentDetail Model:

class ShipmentDetail < ApplicationRecord
  belongs_to :shipment
end

Reform Class

class ShipmentForm < Reform::Form
  property :shipment_type
  property :measure

  property :shipment_detail do
    property :po_number
    property :job_no
  end
end

Controller

class ShipmentsController < ApplicationController
  def new
    @shipment = ShipmentForm.new(Shipment.new)
  end
end

Template

<%= form_for @shipment, url: shipments_path, method: :post do |f| %>
  <%= f.label :shipment_type %><br />
  <%= f.text_field :shipment_type %><br /><br />

  <%= f.label :measure %><br />
  <%= f.text_field :measure %><br /><br />

  <%= f.fields_for :shipment_detail do |d| %>
    <%= d.label :po_number %><br />
    <%= d.text_field :po_number %><br /><br />

    <%= d.label :job_no %>
    <%= d.text_field :job_no %><br /><br />
  <% end %>
<% end %>

Only fields shipment_type and measure are visible on the form, po_number and job_no are not. What should I do to make them visible?


Solution

  • In Reform you need to use a prepopulator to create a new/blank :shipment_detail section to appear on the form.

    http://trailblazer.to/gems/reform/prepopulator.html

    Here is what I used in my code you can get the idea for yours from it:

       collection :side_panels, form: SidePanelForm,
        prepopulator: ->(options) {
          if side_panels.count == 0
            self.side_panels << SidePanel.new(sales_order_id: sales_order_id, collection: sales_order.collection)
          end
        }
    

    RE: The edit form

    If you create a ShipmentForm in the new action and leave the details section blank and later you want to have these fields appear on the edit action you need to run the prepopulators again on that action too. Just like the new action.

    In my code above I have if side_panels.count == 0 line will add in the missing lines on the editing form if there is none there currently.