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?
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
}
Prepopulation must be invoked manually.
Controller#new
@shipment_form = ShipmentForm.new(Shipment.new)
@shipment_form.shipment_detail #=> nil
@shipment_form.prepopulate!
@shipment_form.shipment_detail #=> <nested ShipmentDetailForm @model=<ShipmentDetail ..>>
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.