5

I'm trying to make a nested form with form_for and fields_for. After much research and in-success, not working on my project anymore. I'm just trying to recreate a railscast to see what have I done wrong.

I'm trying to re-create the example found at http://railscasts.com/episodes/196-nested-model-form-part-1 which shouldn't be that hard since the code is there, but I can't manage to create questions from the survey. Here is my code until now:

rails new surveysays
rails g scaffold survey name:string
rake db:migrate
rails g scaffold question survey_id:integer content:text
rake db:migrate

I'm trying to do in the exact same sequence of the video. My Question model:

class Question < ActiveRecord::Base
  belongs_to :survey
end

My Survey model:

class Survey < ActiveRecord::Base
  has_many :questions, dependent: :destroy
  accepts_nested_attributes_for :questions
end

My survey form with nested questions fields:

<%= form_for(@survey) do |f| %>
      ...
      <div class="field">
        <%= f.label :name %><br>
        <%= f.text_field :name %>
      </div>
      <%= f.fields_for :questions do |builder| %>
        <p>
          <%= builder.label :content, "Question" %><br/>
          <%= builder.text_area :content, :row => 3 %>
        </p>
      <% end %>
      <div class="actions">
        <%= f.submit %>
      </div>
   <% end %>

My survey show:

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @survey.name %>
</p>

<ol>
  <% for question in @survey.questions %>
   <li><%=h question.content%></li>
  <% end %>
</ol>

<%= link_to 'Edit', edit_survey_path(@survey) %> |
<%= link_to 'Back', surveys_path %>

And my SurveysController:

class SurveysController < ApplicationController
 ...

  # GET /surveys/new
  def new
    @survey = Survey.new
    3.times { @survey.questions.build }
  end

 ...

  # POST /surveys
  # POST /surveys.json
  def create
    @survey = Survey.new(survey_params)

    respond_to do |format|
      if @survey.save
        format.html { redirect_to @survey, notice: 'Survey was successfully created.' }
        format.json { render :show, status: :created, location: @survey }
      else
        format.html { render :new }
        format.json { render json: @survey.errors, status: :unprocessable_entity }
      end
    end
  end

  ...

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_survey
       @survey = Survey.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def survey_params
       params.require(:survey).permit(:name)
    end
end

As until min 5:34 and thats when it doesn't work as shown in the video and doesn't create the questions, the form appears with the 3 questions, I fill the form, but when a press create it doesn't create the questions:

Loading development environment (Rails 4.1.6) 2.1.3 :001 > s = Survey.all Survey Load (3.0ms) SELECT "surveys".* FROM "surveys" => #]> 2.1.3 :002 > q = s[0].questions Question Load (0.6ms) SELECT "questions".* FROM "questions" WHERE "questions"."survey_id" = ? [["survey_id", 2]] => #

I can't see any difference between my code and the example. I even tried to make some alterations in the SurveysController without any success:

Inserting question_attributes:[:id ,:content] in permit of method survey_params or Inserting @survey.questions.create(survey_params[:questions_attributes]) after if survey.save on create method, this creates the question but with content: nill

At this point I am stuck. I don't know what more what to do, what am I missing int the controller? Can anyone give me some help, thanks.

2 Answers 2

13

On the survey_params method in the controller, you are missing the question params, it should look like:

def survey_params
 params.require(:survey).permit(:name, :questions_attributes => [:question, :answer ... or whatever attribute for the question model])
end

Let me know how it goes!

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, yes i found it a bit ago, I was actually coming here to answer my post. Thanks for the help
2

The survey_params needs to change to permit the nested attributes, from:

def survey_params
   params.require(:survey).permit(:name)
end

to:

def survey_params
  params.require(:survey).permit(:name, questions_attributes: [:id , :content])
end

1 Comment

questions_attributes: [:id , :content, :_destroy] may be a better fit if destroying associations is also required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.