具有 has_one 关系的两层深度嵌套形式中的不允许参数

Unpermitted Parameters in a two level deep nested form with has_one relationship

尽管我一直在获取未经许可的属性错误,但我已经在考试控制器中允许了这些属性。

第一层嵌套工作正常。第二关,答案不保存,服务器说"unpermitted parameters: answers"

如有任何帮助,我们将不胜感激

型号exam.rb

 class Exam < ActiveRecord::Base

    mount_uploader :attachment, PdfUploader #mount the pdf uploader

    validates_presence_of :title, :date, :unit 

    belongs_to :unit

    has_many :questions, :dependent => :destroy

    accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:question].blank? }, :allow_destroy => true
end

问题模型question.rb

class Question < ActiveRecord::Base
belongs_to :exam

has_one :answer, :dependent => :destroy

accepts_nested_attributes_for :answer#, :reject_if => lambda { |a| a[:answer].blank? }, :allow_destroy => true
end

答案模型answers.rb

class Answer < ActiveRecord::Base
belongs_to :question
end

exams_controller.rb

 def new
@exam = Exam.new
2.times do
  question = @exam.questions.build()
  1.times{ question.build_answer }
end

结束

def exam_params
  params.require(:exam).permit(:title, :attachment, :date, :unit_id, 
    questions_attributes:[ :id, :question, :exam_id,  :_destroy,
      answer_attributes:[:id, :answer, :question_id, :_destroy]]
    )
end

_form.html.haml

    .field
    = f.label :Exam_Title
    = f.text_field :title , size: 100
  .field
    = f.label :date
    = f.datetime_select :date
  .field
    = f.fields_for :questions do |builder|
      =render "questions/question_fields", :f => builder

question_fields.html.haml部分

%br/
= f.label :question, "Question"
%br/
= f.text_area :question
%br/
= f.check_box :_destroy
= f.label :_destroy, "Remove Question"

= f.fields_for :answers, @question.answer do |builder|
    =render "answers/answer_fields", :f => builder

answer_fields.html.haml部分

%br/
= f.label :answer, "Answer"
= f.text_field :answer
= f.check_box :_destroy
= f.label :_destroy, "Remove Answer"

服务器响应

 Processing by ExamsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Wns/Q8BAnzge2swUgCmY7yOex3CfUBkViUmiyp7enYMTbeMi+orYS9v7Brqrn7+eTenkaMl9H69vYCt2iqmVcg==", "exam"=>{"title"=>"Now with Answers", "date(1i)"=>"2015", "date(2i)"=>"11", "date(3i)"=>"5", "date(4i)"=>"12", "date(5i)"=>"41", "questions_attributes"=>{"0"=>{"question"=>"What is this?", "_destroy"=>"0", "answers"=>{"answer"=>"This is what", "_destroy"=>"0"}, "id"=>"22"}, "1"=>{"question"=>"What is that?", "_destroy"=>"0", "answers"=>{"answer"=>"That is that!", "_destroy"=>"0"}, "id"=>"23"}}, "unit_id"=>"4"}, "commit"=>"Save", "id"=>"14"}
  Exam Load (0.3ms)  SELECT  "exams".* FROM "exams" WHERE "exams"."id" =  LIMIT 1  [["id", 14]]
Unpermitted parameter: answers
Unpermitted parameter: answers
   (0.1ms)  BEGIN
  Question Load (0.2ms)  SELECT "questions".* FROM "questions" WHERE "questions"."exam_id" =  AND "questions"."id" IN (22, 23)  [["exam_id", 14]]
  Unit Load (0.3ms)  SELECT  "units".* FROM "units" WHERE "units"."id" =  LIMIT 1  [["id", 4]]
  (0.2ms)  COMMIT

更新

变化中:

def exam_params
  params.require(:exam).permit(:title, :attachment, :date, :unit_id, 
    questions_attributes:[ :id, :question, :exam_id,  :_destroy,
      answers_attributes:[:id, :answer, :question_id, :_destroy]]
    )
end

收件人:

def exam_params
  params.require(:exam).permit(:title, :attachment, :date, :unit_id, 
    questions_attributes:[ :id, :question, :exam_id,  :_destroy,
      answer:[:id, :answer, :question_id, :_destroy]]
    )
end

还是不行。将其更改为

def exam_params
  params.require(:exam).permit(:title, :attachment, :date, :unit_id, 
    questions_attributes:[ :id, :question, :exam_id,  :_destroy,
      answers:[:id, :answer, :question_id, :_destroy]]
    )
end

Returns一个错误:

ActiveRecord::UnknownAttributeError (unknown attribute 'answers' for Question.):

在我的 Rails 控制台上:

 question.answer


=> #<Answer id: nil, answer: nil, created_at: nil, updated_at: nil, question_id: 21> 

还是不明白是怎么回事。请帮帮我。

为表单呈现 HTML:

 <div class='field'>
    <br>
    <label for="exam_questions_attributes_0_question">Question</label>
    <br>
    <textarea name="exam[questions_attributes][0][question]" id="exam_questions_attributes_0_question">
What is this?</textarea>
    <br>
    <input name="exam[questions_attributes][0][_destroy]" type="hidden" value="0" /><input type="checkbox" value="1" name="exam[questions_attributes][0][_destroy]" id="exam_questions_attributes_0__destroy" />
    <label for="exam_questions_attributes_0__destroy">Remove Question</label>
    <br>
    <label for="exam_questions_attributes_0_answers_answer">Answer</label>
    <input type="text" name="exam[questions_attributes][0][answers][answer]" id="exam_questions_attributes_0_answers_answer" />
    <input name="exam[questions_attributes][0][answers][_destroy]" type="hidden" value="0" /><input type="checkbox" value="1" name="exam[questions_attributes][0][answers][_destroy]" id="exam_questions_attributes_0_answers__destroy" />
    <label for="exam_questions_attributes_0_answers__destroy">Remove Answer</label>
    <input type="hidden" value="22" name="exam[questions_attributes][0][id]" id="exam_questions_attributes_0_id" /><br>
    <label for="exam_questions_attributes_1_question">Question</label>
    <br>
    <textarea name="exam[questions_attributes][1][question]" id="exam_questions_attributes_1_question">
What is that?</textarea>
    <br>
    <input name="exam[questions_attributes][1][_destroy]" type="hidden" value="0" /><input type="checkbox" value="1" name="exam[questions_attributes][1][_destroy]" id="exam_questions_attributes_1__destroy" />
    <label for="exam_questions_attributes_1__destroy">Remove Question</label>
    <br>
    <label for="exam_questions_attributes_1_answers_answer">Answer</label>
    <input type="text" name="exam[questions_attributes][1][answers][answer]" id="exam_questions_attributes_1_answers_answer" />
    <input name="exam[questions_attributes][1][answers][_destroy]" type="hidden" value="0" /><input type="checkbox" value="1" name="exam[questions_attributes][1][answers][_destroy]" id="exam_questions_attributes_1_answers__destroy" />
    <label for="exam_questions_attributes_1_answers__destroy">Remove Answer</label>
    <input type="hidden" value="23" name="exam[questions_attributes][1][id]" id="exam_questions_attributes_1_id" />  
  </div>
  <div class='field'>
    <label for="exam_unit">Unit</label>
    <select name="exam[unit_id]" id="exam_unit_id"><option value="1">Introduction to Comp Science</option>
    <option value="2">Human Computer Interaction</option>
    <option value="3">Management Information Systems</option>
    <option selected="selected" value="4">Management Information Systems II</option></select>
  </div>
  <div class='actions'>
    <input type="submit" name="commit" value="Save" />
  </div>

问题在这里:

"answers"=>{"answer"=>

这应该是 "answers_attributes"=>{"answer"(就像 questions 一样)。

原因是您还没有在您的控制器中构建answer对象(或者至少正确地构建了它):

def new
   @exam = Exam.new
   2.times do
     @exam.questions.build.build_answer
   end
end

这应该可以正常工作。

我想我已经解决了。问题是,我必须添加编辑我的 exam.rb 模型,使其看起来像这样:

belongs_to :unit

has_many :questions, :dependent => :destroy

has_many :answers, :through => :questions

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

注意:我创建了一个名为 response 的新模型,其字段与 answer 完全相同,并按照 Rich Peck[=20 的建议编辑了我的 exam_controller.br =]

向我的父模型添加行 has_many :answers, :through => :questions 似乎解决了这个问题。 现在 parameter response 改为 response_attributes 应该是。

谢谢,Rich Peck 真的很有帮助。