Search code examples
ruby-on-railsrubyassociationsnested-formscocoon-gem

Rails - Cocoon Gem - populating foreign key id


I am trying to use simple form with cocoon gem to nest children forms inside a parent class form.

I have models for proposal and pitch.

The associations are:

Proposal

  has_one :pitch, inverse_of: :proposal
    accepts_nested_attributes_for :pitch, reject_if: :all_blank, allow_destroy: true

Pitch

  belongs_to :proposal, inverse_of: :pitch

In my proposal form, I have:

<%= f.simple_fields_for :pitch do |f| %>
        <%= f.error_notification %>
          <%= render 'pitches/pitch_fields', f: f %>

      <% end %>

      <%= link_to_add_association 'Pitch', f, :pitch, partial: 'pitches/pitch_fields' %> 

In my proposal controller, I have:

def new
    @proposal = Proposal.new
    @proposal.build_pitch
    # authorize @proposal
  end

  def edit
    @proposal.build_pitch unless @proposal.pitch
  end


def proposal_params
      params.require(:proposal).permit(:title, :description, 

        pitch_attributes:       [:id, :problem, :solution, :remark, :_destroy ])
    end

pitches/_pitch_fields.html.erb has:

<div class="nested-fields">
    <div class="form-inputs">
        <%= f.input :problem, as: :text, 
          # :label =>  text_for_problem(current_user, @pitch.proposal), 
          :label =>  'What issue does this proposal address?', 
          :input_html => {:rows => 10} %>
      </div>

When I save all this and try it, the form loads and I can complete the form, but the foreign key for proposal_id saves as nil.

If I try to edit the form, I get an error that says:

Couldn't find Pitch with ID=5 for Proposal with ID=10

When I try:

pitch.errors.full_messages
NameError: undefined local variable or method `pitch' for main:Object

What do I need to do in order to force the proposal_id attribute in the pitch table to be set with the proposal id?


Solution

  • This is a bit weird, and imho a bug in rails, but the link_to_add_association will try to build a new pitch to be able to render it correctly. This will effectively delete the existing pitch.

    So the solution is to add the option force_non_association_create: true on link_to_add_association. Or just drop the link_to_add_association altogether: why do you need it? You can have only one pitch, and you always create it if it does not exist?