Reputation: 743
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 %>
Upvotes: 0
Views: 205
Reputation: 553
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]
Upvotes: 3