Rails 5 Independent View Nested Resource - param is missing or the value is empty

mazing Source

I have a nested resource called PracticeQuestion, which is a child of PracticeQuiz. I want users to be able to go through one question at a time when they are at a PracticeQuiz. For example: foo.com/practice_quizzes/1/practice_questions/1..n

I got the practice quizzes working, but when I try to add a new practice question, I get a rails error that says that the param is missing or empty, but I don't see what i'm doing wrong. Please help

practice_quiz.rb

class PracticeQuiz < ApplicationRecord
  belongs_to :user, optional: true
  validates :user, presence: true
  has_many :practice_questions, dependent: :destroy
end

practice_question.rb

class PracticeQuestion < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :practice_quiz
end

practice_questions_controller.rb

class PracticeQuestionsController < ApplicationController
  before_action :set_practice_question, only: [:show, :edit, :update, :destroy]
  def index
    @practice_questions = PracticeQuestion.all
  end

  def show
  end

  # GET /practice_questions/new
  def new
    @practice_quiz = PracticeQuiz.friendly.find(params[:practice_quiz_id])
    @practice_question = PracticeQuestion.new
  end

  # GET /practice_questions/1/edit
  def edit
  end


  def create
    @practice_quiz = PracticeQuiz.friendly.find(params[:practice_quiz_id])
    @practice_question = PracticeQuestion.new(practice_question_params)

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

  private
    def set_practice_question
      @practice_question = PracticeQuestion.find(params[:id])
    end

    def practice_question_params
        params.require(:practice_question).permit(:question, :explanation, :flagged)
     end


end

views/practice_questions/_form.html.erb

<%= form_with(url: practice_quiz_practice_questions_path, local: true) do |form| %>
  <% if practice_question.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(practice_question.errors.count, "error") %> prohibited this practice_question from being saved:</h2>

      <ul>
      <% practice_question.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>


  <div class="field">
    <%= form.label :question %>
    <%= form.text_field :question %>
  </div>

  <div class="field">
    <%= form.label :explanation %>
    <%= form.text_field :explanation %>
  </div>


  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

routes.rb

  resources :practice_quizzes do 
    resources :practice_questions
  end

I set the practice_questions controller's new method to find the id of the parent resource, but I get this error. I'm pretty sure I'm following rails naming conventions fine too.

ActionController::ParameterMissing at /practice_quizzes/23535/practice_questions param is missing or the value is empty: practice_question

Update: here's the results from the rails server window

Processing by PracticeQuestionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"7dpxBB7jjZWzicCYWGA8yeTPSc9UeaqNDOavKQai2vMISryPBiMZ9Zo4LLS3DgZQI8IJc7rLh2TXd9Fj8PAjiA==", "question"=>"235235", "explanation"=>"25235232", "commit"=>"Save ", "practice_quiz_id"=>"23535"}
  User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  PracticeQuiz Load (0.9ms)  SELECT  "practice_quizzes".* FROM "practice_quizzes" WHERE "practice_quizzes"."slug" = $1 ORDER BY "practice_quizzes"."id" ASC LIMIT $2  [["slug", "23535"], ["LIMIT", 1]]
Completed 400 Bad Request in 102ms (ActiveRecord: 1.7ms)

ActionController::ParameterMissing - param is missing or the value is empty: practice_question:
  app/controllers/practice_questions_controller.rb:76:in `practice_question_params'
  app/controllers/practice_questions_controller.rb:30:in `create'

Update 2:

views/practice_questions/new.html.erb

<h1>New Practice Question</h1>
<%= render 'form', practice_question: @practice_question %>
ruby-on-railsruby

Answers

answered 7 months ago Leaf #1

Here

def practice_question_params
    params.require(:practice_question).permit(:question, :explanation, :flagged)
end

you are using rails strong parameters. See this answer https://stackoverflow.com/a/30826895/2627121

Basically, params.require(:practice_question) means that you must have practice_question parameter. Here Parameters: {"utf8"=>"✓", "authenticity_token"=>"", "question"=>"235235", "explanation"=>"25235232", "commit"=>"Save ", "practice_quiz_id"=>"23535"} you have question and explanation as root parameters, when according to your strong parameters declaration you must have "practice_question" => { "question"=>"235235", "explanation"=>"25235232" }

You should edit form fields to have name as practice_question[question]

comments powered by Disqus