Rails中的嵌套模型表单

时间:2014-10-06 00:27:29

标签: ruby-on-rails forms nested-forms

我正在尝试创建一个可用于提交测验答案的网络应用。我在创建视图文件时遇到了麻烦。

提交表单应该看起来像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相关联,而不是视图中,正如我最初尝试的那样。将尝试通过你的建议,并将回复。但似乎这条线将解决我所有的问题: - )

2 个答案:

答案 0 :(得分:1)

使用适当的连接表。建议您使用“答案”表格来表示用户的实际答案。使用question_optionsoption_groups获取问题的可能答案。

建议您考虑将其基于https://stackoverflow.com/a/5858666/631619

只需将“调查”替换为“测验”

enter image description here

答案 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添加到您的表单