Search code examples
ruby-on-railsbelongs-toapache-cocoon

Rails 5.0 with Cocoon: Issue with belongs_to inside of nested fields


I've got three models:

Model P

has_many :svs
has_many :gs, through: svs
accepts_nested_attributes_for :svs

Model SV

belongs_to :p
belongs_to :g
accepts_nested_attributes_for :g

Model G

has_many :svs
has_many :ps, through: svs

What I need is a form for one P that contains one or more nested forms for SVs and each of these SV-forms must have another nested form for exactly one G (slim):

= form_for @p do |p|
        ...
        ...
        = render 'sv_form', f: p
    = p.submit

sv_form

= f.fields_for :svs do |sv|
    `= sv.fields_for :g do |g|`
        ...
        ...
        #sv
            = render 'sv_fields', f: sv, g: g
    .links
        = link_to_add_association 'add sv', f, :svs, partial: 'sv_fields', render_options: {locals: {g: g}}

sv_fields

.nested_fields
    = g.label :name # here is the problem: no random id for these fields
    = g.text_field :name # here also no random id
    = f.label :name
    = f.text_field :name
    ...
    ...
    = link_to_remove_association 'remove SV', f

This works fine as long as I save the P with one SV only. But as soon as I add a second SV this second's SV G-name overrides the first G-name. Inspecting the form with firebug I can see that the random ID is missing for the second G-name so the error becomes clear. Any help appreciated...!


Solution

  • [for ease of readability I will assume P=Patient, SV=SequenceVariation, G=Gene]

    From the comments I understood that each SequenceVariation has a Gene, but when adding a new SequenceVariation no Gene is visible. We can either add a link_to_add_association for a gene, or assuming each sequence-variation must have a gene, prebuild one to be filled. We can do this using the wrap_object option of link_to_add_association :

    = link_to_add_association('add sequence variation', f, :svs, wrap_object: Proc.new {|sv| sv.build_gene; sv })
    

    This will make sure that each new sequence-variation will also have an initialised gene.

    And then the sv_fields partial can be adapted as follows:

    .nested_fields
      = f.label :name 
      = f.text_field :name
      = fields_for :gene do |g|
        = g.label :name
        = g.text_field :name
      = link_to_remove_association 'remove SV', f