【问题标题】:Nested model form in RailsRails 中的嵌套模型表单
【发布时间】:2014-10-06 00:27:29
【问题描述】:

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

提交表单应类似于this(抱歉,不允许我在问题正文中插入图片)。

这是 Ryan Bates 在 Railscasts 中讨论的嵌套模型形式的一个案例,但有一个重要的区别。在 Ryan Bates 的案例中,有一个简单的关联链:一个调查模型有很多问题,每个问题都有很多答案。

不过,我的计划要复杂一些。在我的例子中,一个测验有很多问题,一个问题有很多答案,但是向用户展示的是一个称为提交的模型。提交与用户模型和答案模型相关联,并且它还具有一些附加信息。从示意图上看,我的关联看起来像 this:

所以我需要创建一个表单,它将模型(提交)与许多未关联的模型(问题)和许多关联的模型(答案)结合起来。对于我的新/编辑视图文件,我所能想到的就是:

控制器:

  # 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 和答案之间没有关联。如果 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 相关联,而不是在视图中,就像我最初尝试做的那样。将尝试完成您的建议并回信。但似乎这条线会解决我所有的问题:-)

【问题讨论】:

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


    【解决方案1】:

    使用适当的连接表。建议您对用户做出的实际答案使用“答案”表。使用question_options 和option_groups 获取问题的可能答案。

    建议你考虑基于https://stackoverflow.com/a/5858666/631619

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

    【讨论】:

      【解决方案2】:

      我做了一些非常相似的事情,我可以给你一些建议:

      首先,我建议你使用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 添加到您的表单中

      【讨论】:

      • 我已经完成了将数据从控制器发送到视图然后返回控制器并进入数据库的完整循环,我很高兴地说一切正常。您为控制器建议的行@questions.each { |q| @submission.answers.build question_id: q.id } 确实是一个突破。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多