Ассоциации областей для модели, используемой несколько раз в одной форме с simple_form и cocoon

#ruby-on-rails #ruby #simple-form #cocoon-gem

#ruby-on-rails #ruby #простая форма #cocoon-gem

Вопрос:

Я оказался в следующей полунормальной ситуации:

 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
  

Рассматриваемая форма — это Contract форма, которая отлично работает в ситуации, когда для каждого связанного местоположения я выбираю местоположение и роль. С архитектурной точки зрения это работает, но поскольку у меня фактически есть два Location «типа» ( :shipper и :receiver ), я бы хотел иметь их в виде двух отдельных частей формы. Таким образом, по сути, раздел формы со своей собственной кнопкой «добавить местоположение доставки» и другой раздел со своей собственной кнопкой «добавить местоположение получения». Я могу добиться этого, но проблема, которую это вызывает, заключается в том, что форма заполняется из существующих отношений. Если я отправлю форму следующим образом:

Снимок экрана 2019-03-21 в 13:44 11

И я снова загружаю форму редактирования, значения заполняются следующим образом:

Снимок экрана 2019-03-21 в 13:45 19

Очевидно, это потому, что cocoon просто заполняет связанные Location s, как и предполагалось, и не различает Location s с конкретными role s. Существуют ли какие-либо функции области, которые позволили бы мне создавать эти элементы формы только для Location s для некоторой конкретной области (как в role: :shipper )?

РЕДАКТИРОВАТЬ: Я должен отметить, что я пытался использовать предоставленные обратные вызовы Javascript, в частности before-insert , но не похоже, что они запускаются при загрузке формы в первый раз.

Ответ №1:

Я решил свою проблему, хотя мне все еще интересно посмотреть, есть ли встроенный в Cocoon способ решить это.

Мое решение — проверить объект формы в моем 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 %>