Search code examples
ruby-on-railssimple-formcocoon-gem

Cocoon First Option Not Saving - Nested Fields


I'm using Cocoon for a nested form, however the first set of fields do not save into the database, if I create a second row they seem to save just fine?

I'm guessing its just something I'm overlooking

class Form < ActiveRecord::Base
    has_many :questions
    accepts_nested_attributes_for :questions, :reject_if => :all_blank, :allow_destroy => true
end

class Question < ActiveRecord::Base
    belongs_to :form
end

----- form_controller.rb

def new
  @form = Form.new
  @form.questions.build
end 

def create
  @form = Form.new(form_params)

  if @form.save
     redirect_to action: "show", id: @form.id
  else
     render('new')
  end
end

def form_params
 params.require(:form).permit(:title, :description, :status, questions_attributes: [:form_id, :question_type, :question_text, :position,   :answer_options, :validation_rules, :done, :_destroy])
end

<%= simple_form_for Form.new ,:url => {:action => :create} do |f| %>
    <div class="section-row"> 
      <div class="section-cell">
        <%= f.label :title, "Form Title" %>
        <%= f.text_field :title, placeholder: "Form Title" %>
        <br/></br>
        <%= f.label :description, "Form Description" %>
        <%= f.text_area :description, placeholder: "Form Description" %>
        <%= f.hidden_field :status, value: "online" %>
      </div>
    </div>
    <div class="section-row"> 
      <div class="section-cell">
        <div id="questions">
          <%= simple_fields_for :questions do |question| %>
            <%= render 'question_fields', :f => question %>
            <%= link_to_add_association 'add question', f, :questions %>
          <% end %>
        </div>
      </div>
    </div>
    <div class="section-row"> 
      <div class="section-cell">
        <%= f.submit "Create Ticket", class: "btn btn-primary btn-lg" %>
      </div>
    </div>
  <% end %>

---- _question_fields.html.erb

<div class='nested-fields'>
    <%= f.label :question_type, "Question Type" %>
    <%= f.select :question_type, 
options_for_select([['Text Box','textbox'],['Dropdown Options','select'],   ['Mutiple Choice','radio']], params[:question_type]),
{}, { :class => '' } %>
</div>

Solution

  • You forgot the f in front of the simple_fields_for : then the simple_fields_for has no knowledge of the form, nor the associations, so it will name the parameters posted to the controller differently, so it will be blocked by your strong parameters definition.

    So if you write

    f.simple_fields_for :questions do |question|
    

    it should just work ;)

    Smaller remarks:

    • the link_to_add_association should be outside of the loop, otherwise it will not be visible if there are none, and will be displayed for each question (which may or may not make sense in your UI).
    • you should add the id inside the strong parameters for questions_attributes (important for editing/deleting)