I've found myself in the following semi-normal situation:
class Contract
has_many :contract_locations, dependent: :destroy
has_many :locations, through: :contract_locations
end
class ContractLocation
enum role: { shipper: 0, receiver: 1 }
belongs_to :contract
belongs_to :location
end
class Location
has_many :contract_locations, dependent: :destroy
has_many :contracts, through: :contract_locations
end
The form in question is the Contract
form, which is working fine in the situation where, for each associated location, I select a location and a role. Architecturally, this works, but because I effectively have two Location
"types" (:shipper
and :receiver
), I'd like to have them as two separate parts of the form. So essentially a section of the form with its own "add shipping location" button and another section with its own "add receiving location" button. I'm able to achieve this, but the problem it causes is when the form is being populated from existing relationships. If I submit the form like this:
And I load the edit form again, the values are filled like this:
Clearly this is because cocoon is just filling in the associated Location
s as it's supposed to, and doesn't distinguish between Location
s with specific role
s. Are there any scoping features that would allow me to only create these form elements for Location
s for some specific scope (as in role: :shipper
)?
EDIT: I should note that I've tried using the provided Javascript callbacks, particularly before-insert
, but it doesn't look like they trigger when the form is loaded for the first time.
I've solved my issue, though I'm still interested to see if there's a way built-in to Cocoon to solve this.
My solution is to check the form object in my cocoon partial:
<%= f.simple_fields_for :contract_locations do |contract_location| %>
<!-- This check prevents locations of the wrong role being rendered in the wrong form section. -->
<% if contract_location.object.role == role.to_s %>
<%= render 'form_location_fields', f: contract_location, role: role %>
<% end %>
<% end %>