好的,这个问题有点开放式,但是这里......
首先,您可能只需要一种形式来实现这一目标。它可以包含许多字段,但最好将您想要的所有内容放在一个表单中(否则您将需要使用一些 javascript 恶作剧来将数据放在一起)。
所以现在我们的视图开始看起来像这样:
<b>questions:</b>
<%= form_tag do %>
<% @i=1 %>
<% @assignment.questions.each do |q| %>
<p>question <%= @i %><p/>
<%= q.content %>
<%=#need to generate text_area fields here %>
<% @i= @i+1%>
<br/>
<% end %>
<% end %>
但是等等 -@i
范围过大,它可能是简单i
的,并且所有这些递增@i
看起来都不是很红润......我们可以将它切换为使用each_with_index方法来清理它......
<%= form_for :answersheet do |f| %>
<b>questions:</b>
<% @assignment.questions.each_with_index do |question, index| %>
<p>question <%= index %><p/>
<%= question.content %>
<%=#need to generate text_area fields here %>
<br/>
<% end %>
<% end %>
嗯,这有点好,但现在很明显,该循环内部的问题可以很容易地抽象成它自己的部分(可能_question.html.erb
):
<p>question <%= question_counter %><p/>
<%= question.content %>
<%=#need to generate text_area fields here %>
<br/>
留给我们:
<%= form_for :answersheet do |f| %>
<b>questions:</b>
<%= render @assignment.questions %>
<% end %>
好的,很好,但是呢<%=#need to generate text_area fields here %>
?在你的部分中这样的东西应该可以解决问题:
<p>question <%= question_counter %><p/>
<%= question.content %>
<%= content_tag :textarea , '' , name: raw( "answers[#{ question_counter }]" ) %>
<br/>
这将允许您在控制器中执行以下操作:
Answersheet.create( answer_responses: params[:answers].values.join(';') ) if params[:answers]
目前,这将发布到与最初呈现页面相同的控制器/动作。您可能希望添加一个额外的路由来将其发送到它自己的控制器/动作 - 您可以将该路由作为参数提供给form_tag。此外,这没有考虑可能输入无效数据的可能性,在向用户显示错误消息时需要保留这些数据。它也不考虑重定向用户,或在成功提交时显示成功消息。如果您需要更多复杂性,您可以考虑切换到form_for并使用答案表的实际实例,以及更适当的宁静路线。在这个例子中,我故意没有使用 form_for,因为模型不能直接使用正在发送的数据。您可能会考虑在答案表上创建answers
一个方法,该方法在answer_responses
保存之前被输入,或者如果追求该路线(或者可能在提交时使用 javascript 进行,这感觉不是一个好主意)。就像我说的,有点开放。无论如何,这应该足以让你指出正确的方向——祝你好运!