I'm having some trouble getting a form to render correctly for a nested model. Basically, I have 2 models a Question
model and an Answer
model. The Question
models has_many
Answers
and an Answer
belongs_to
a Question
. So, as per the documentation here and here, I've set up my model, controller and form as follows:
Question
Model:
class Question < ActiveRecord::Base
has_many :answers, :dependent => :destroy
accepts_nested_attributes_for :answers, :reject_if => lambda {|attrib| attrib[:content].blank? }, :allow_destroy => true
validate :validate_answers
def validate_answers
remaining_answers = answers.reject(&:marked_for_destruction?)
errors.add :answers, "At least 4 answers are required." if remaining_answers < 4
end
end
Answer
Model:
class Answer < ActiveRecord::Base
belongs_to :question
end
questions_controller.rb
class QuestionsController < ApplicationController
before_action :set_question, only: [:show, :edit, :update, :destroy]
# GET /questions
# GET /questions.json
def index
@questions = Question.all
end
# GET /questions/1
# GET /questions/1.json
def show
end
# GET /questions/new
def new
@question = Question.new
4.times { @question.answers.build }
end
# GET /questions/1/edit
def edit
end
# POST /questions
# POST /questions.json
def create
@question = Question.new(question_params)
respond_to do |format|
if @question.save
format.html { redirect_to @question, notice: 'Question was successfully created.' }
format.json { render :show, status: :created, location: @question }
else
format.html { render :new }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /questions/1
# PATCH/PUT /questions/1.json
def update
respond_to do |format|
if @question.update(question_params)
format.html { redirect_to @question, notice: 'Question was successfully updated.' }
format.json { render :show, status: :ok, location: @question }
else
format.html { render :edit }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
# DELETE /questions/1
# DELETE /questions/1.json
def destroy
@question.destroy
respond_to do |format|
format.html { redirect_to questions_url, notice: 'Question was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_question
@question = Question.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit()
end
end
and the app/views/questions/_form.html.erb
:
<%= simple_form_for @question do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<p>
<%= f.label :question_stem, "Question" %>
<%= f.text_area :question_stem, :rows => 3 %>
</p>
<p>
<% f.simple_fields_for :answers do |builder| %>
<%= builder.label :answer_text, "Answer" %><br>
<%= builder.text_area :answer_text %>
<% end %>
</p>
</div>
<div class="form-actions">
<%= f.button :submit, "Create Question" %>
</div>
<% end %>
However, when I point my browswer to http://localhost:3000/questions/new
this is what I get:
Any idea what is going on? The rails console shows that the request was received and that the form was rendered:
Started GET "/questions/new" for 127.0.0.1 at 2015-08-27 01:03:57 -0500
Processing by QuestionsController#new as HTML
Rendered questions/_form.html.erb (4.9ms)
Rendered questions/new.html.erb within layouts/application (17.3ms)
Completed 200 OK in 221ms (Views: 179.1ms | ActiveRecord: 1.2ms)
I'm stumped as to why the fields for the answer model aren't being rendered. Any help is much appreciated!
The problem is because you are missing =
here in this line <% f.simple_fields_for :answers do |builder| %>
It should be
<%= f.simple_fields_for :answers do |builder| %>