Question

My Ruby on Rails 4 form creates a question. I want to also add the ability to create 4 answers to the question. It is creating the question but no answers. It is not posting to the answers table, only the questions table.

How do you get it to post to the answers to the answers table?

My log POST:

Started POST "/questions" for x at 2014-04-17 13:16:21 -0700
Processing by QuestionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x", "question"=>{"content"=>"Test question 2", "question_type"=>"MC", "category"=>"i
p_voice", "product_id"=>"1", "active"=>"0", "answers_attributes"=>{"0"=>{"content"=>"one piggy", "correct"=>"1", "question_id"=>""}, "1"=>{"content"=>"two elephants", "correct"=>
"0", "question_id"=>""}, "2"=>{"content"=>"one lion", "correct"=>"0", "question_id"=>""}, "3"=>{"content"=>"six oranges", "correct"=>"0", "question_id"=>""}}}, "commit"=>"Create 
Question"}
Unpermitted parameters: answers_attributes
(0.1ms)  begin transaction
SQL (0.3ms)  INSERT INTO "questions" ("active", "category", "content", "created_at", "product_id", "question_type", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["active", fals
e], ["category", "ip_voice"], ["content", "Test question 2"], ["created_at", Thu, 17 Apr 2014 20:16:21 UTC +00:00], ["product_id", 1], ["question_type", "MC"], ["updated_at", Thu
, 17 Apr 2014 20:16:21 UTC +00:00]]
(31.5ms)  commit transaction

My questions_controller

def new
@question = Question.new
4.times { @question.answers.build }

@products = Product.all
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(:content, :question_type, :category, :product_id, :active)
end

# Before filters
def signed_in_user
    unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
    end
end

My answers_controller

def new
@answer = Answer.new
end

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

# Never trust parameters from the scary internet, only allow the white list through.
def answer_params
  params.require(:answer).permit(:content, :question_id, :correct)
end

# Before filters
def signed_in_user
    unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
    end
end

My question.rb model

class Question < ActiveRecord::Base
has_many :answers, dependent: :destroy
belongs_to :user
accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:contecnt].blank? }, :allow_destroy => true

My answer.rb model

belongs_to :question    

My Form!

<h1>New question</h1>
<%= form_for(@question) do |f| %>
<%= render 'shared/error_questions' %>
<%= render 'form', f: f %>
<h1>Answers</h1>
<%= f.fields_for :answers do |builder| %>
<%= render 'four_answers', :f => builder %>
<% end %>
    <%= f.submit "Create Question", class: "btn btn-lg btn-primary" %>
<% end %>
Was it helpful?

Solution

Looks like the accepts_nested_attributes_for is always getting rejected with the reject_if option. Your a[:contectnt].blank? is always true because the key contectnt does not exist in the hash.

Use :reject_if => lambda { |a| a[:content].blank? } as follows:

accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true

Update and I suppose the accurate answer!:

As the log shows you are not permitting answers_attributes through mass assignment, you also need to add answers_attributes to the permit list as follows:

# app/controllers/questions_controller.rb
def question_params
  params.require(:question).permit(:question_type, :category, :product_id, :active, answers_attributes: [ :content, :correct, :question_Id ] )
end

Please see Strong Parameters at edgeapi for further details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top