3

私は、has_many:questionsモデルを持つassignmentというモデルを持っています。これは、assignment_toに属します。質問には、コンテンツと呼ばれる文字列フィールドがあります。私の割り当てのshow.html.erbには、各質問を繰り返して表示するループがあります。

<b>questions:</b>
  <% @i=1 %>
  <% @assignment.questions.each do |q| %>
      <p>question <%= @i %><p/> 
      <%= q.content %>
       <%=#need to generate text_area forms here %>
      <% @i= @i+1%>
      <br/>
  <% end%>

ユーザー(has_many:answersheetsモデル、次にbelongs_to:student)は、回答を入力してから[送信]をクリックする必要があります。送信では、新しい回答シートオブジェクト(文字列としてstudent_idassignment_id列とanswer_responses列があります)を作成する必要があります。すべての回答を文字列として取得し、それらを連結して( ";"などの間に仕切りを入れて)、新しく作成された回答シートモデルのanswer_responsesをその文字列に設定する必要があります。

4

1 に答える 1

3

OK、この質問は少し自由回答ですが、ここでは...

まず第一に、この目的を達成するために必要なフォームは 1 つだけです。多くのフィールドを含めることができますが、必要なものをすべて 1 つのフォームにまとめておくことをお勧めします (そうしないと、データをまとめるためにいくつかの 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

<%= 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 を使用して実行することは、あまり良い考えではないように感じます)。私が言ったように、少しオープンエンドです。いずれにせよ、これで正しい方向に進むには十分すぎるはずです。幸運を祈ります!

于 2012-12-01T07:31:55.547 に答える