我正在尝试创建一个可用于提交测验答案的网络应用。我在创建视图文件时遇到了麻烦。
提交表单应该看起来像this(抱歉,我不允许我在问题正文中插入图片)。
这是Ryan Bates在Railscasts中讨论的嵌套模型形式的一个案例,但是有一个重要的区别。在Ryan Bates'案例中有一个简单的关联链:一个调查模型有很多问题,每个问题都有很多答案。
但我计划的事情有点复杂。在我的例子中,测验有很多问题,而一个问题有很多答案,但用户所呈现的是一个名为提交的模型。提交与用户模型和答案模型相关联,还有一些其他信息。示意性地,我的关联看起来像this:
所以我需要创建一个表单,它将模型(Submission)与许多非关联模型(Questions)和许多相关模型(Answers)结合起来。我能想到的新的/编辑视图文件是:
控制器:
# GET /tests/:test_id/submissions/new
def new
@quiz = Quiz.find(params[:quiz_id])
# the next four lines of code are to select a subset of questions
variant = choose_variant(@quiz)
@submission = Submission.new
@submission.variant = variant
@questions = Question.where (variant: variant)
@questions.each {|question| quiestion.answers.build}
end
查看:
= form_for [@quiz, @submission] do |f|
= f.fields_for :answers do |builder|
= @questions.each do |question|
%p
= @question.text
= builder.label :answer_text, "Your answer"
= builder.text_area :answer_text
但它看起来并不正确:@submission,@question和答案之间没有关联。如果提交和问题模型之间没有直接关联,你能否建议如何解决这个问题?
更新:
我现在可以在视图中创建一个表单:
= form_for [@quiz, @submission] do |f|
- @questions.each do |question|
%p
= question.text
= f.fields_for :answer, question.answers.first do |builder|
= builder.label :text, "Answer"
= builder.text_area :text
麻烦的是,在提交最后一个答案时会覆盖所有的私密答案,并且在参考资料中我只得到:
"submission"=>{"answer"=>{"text"=>"Answer to the last question"}}
更新2:
致Marcelo Risoli(对不起,我还没有掌握StackOverflow的行为,并且它不允许我写另一条评论)。我道歉,我一开始并不太明白你的建议。您的第@questions.each { |q| @submission.answers.build question_id: q.id }
行是纯粹的天才:它将answers
与控制器中的submission
相关联,而不是视图中,正如我最初尝试的那样。将尝试通过你的建议,并将回复。但似乎这条线将解决我所有的问题: - )
答案 0 :(得分:1)
使用适当的连接表。建议您使用“答案”表格来表示用户的实际答案。使用question_options
和option_groups
获取问题的可能答案。
建议您考虑将其基于https://stackoverflow.com/a/5858666/631619
只需将“调查”替换为“测验”
答案 1 :(得分:0)
我做了一些非常相似的事情,我可以给你一些建议:
首先,我建议您使用cocoon,嵌套表格不再更新,我发现茧更容易处理。
其次,提交不需要与问题相关联,如果有必要,您可以使用has_many ::通过关联访问给定提交的问题。
当你在form_for提交中使用fields_for:answers意味着新创建的submission_id将输入到答案中,现在您只需要输入question_id,您可以通过隐藏输入执行此操作,只需在您的内容中执行以下操作即可控制器:
@questions.each { |q| @submission.answers.build question_id: q.id }
然后将= builder.input :question_id, as: :hidden
添加到您的表单