Search code examples
ruby-on-railsruby-on-rails-4nested-formsstrong-parameters

Rails 4 - Unpermitted Paramaters - Deeply nested attributes form not saving


I'm working on deeply nested attributes and running into this unpermitted attributes error.

Log:

Started POST "/videos/1/quizzes"
Processing by QuizzesController#create as HTML
  Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"XdJ5lPZ7QuVEZiVYbphnV0T/NpMMTKVaL2dcWRxHVQU=", 
"quiz"=>{"name"=>"Test",
"question"=>{"content"=>"Test", 
"answer"=>{"content"=>"Test"}}}, "commit"=>"Submit", "video_id"=>"1"}

 Video Load (0.1ms)  SELECT  "videos".* FROM "videos"  WHERE "videos"."id" = ? LIMIT 1  [["id", 1]]

 Unpermitted parameters: question

So all the data is being submitted. From reading around it looks like the nested question parameters is supposed to be "question_attributes"=> But in my log it just shows "question"=>. I don't know if that has something to do with it? But at this point it's really my only idea.

quizzes#new:

def new
  @video = Video.find(params[:video_id])
  @quiz = @video.build_quiz
  @quiz.questions.build
  @quiz.questions.each do |question|
     question.answers.build
  end
end

The video_id params is working and as you can see above it is being submitted.

quizzes#create

def create
  @video = Video.find(params[:video_id])
  @quiz = @video.create_quiz(quiz_params)
  respond_to do |format|
    if @quiz.save
        format.html { redirect_to @quiz, notice: 'quiz was successfully created.' }
        format.json { render :show, status: :created, location: @quiz }
     else
        format.html { render :new }
        format.json { render json: @quiz.errors, status: :unprocessable_entity }
    end
  end
end

quizzes_params

def quiz_params
   params.require(:quiz).permit(:name, questions_attributes: [:id, :content, :quiz_id, answers_attributes: [:id, :content, :question_id]])
end

So as you can see it's stopping the question parameters and the answer parameters from being saved.

Let me know if you need anything else! Thank you in advance for any help!

Update Here is the form partial! I also tried doing form_for @quiz do |f| but that didn't change what was submitted. The other thing I tried was pluarlizing :question and :answer as :questions and :answers but no luck.

  <%= form_for [@video, @quiz] do |f| %>
    <%= f.label :name, "Title" %>
    <%= f.text_field :name %>

    <%= f.fields_for :question do |questions| %>
      <%= questions.label :content, "Question" %><br>
      <%= questions.text_area :content, rows: 3  %>

      <%= questions.fields_for :answer do |answers| %>
        <%= answers.label :content, "Answer" %>
        <%= answers.text_field :content %>
      <% end  %>

    <% end %>
    <%= f.submit "Submit" %>

  <% end %>

Solution

  • Solution:

    I changed this line in the quizzes_controller from @quiz.questions.build to 2.times { @quiz.questions.build } and it fixed the issue. Not really sure why it works now, but it does. Any explanation as to why would be really appreciated!

    def new
        @video = Video.find(params[:video_id])
        @quiz = @video.build_quiz
        2.times { @quiz.questions.build }
        @quiz.questions.each do |question|
            question.answers.build
        end
    end