定義済みの質問を含むコレクションと、これらすべての質問に回答するユーザーがいます。したがって、ビューは次のようになります。
= form_for @user do |f|
-#some code and then...
%table.table
- @questions.each do |q|
%tr
%td=q.name
%td
%input-# Here the answer of the user for the question 'q'
したがって、ビューには、各質問に対する各ユーザーの回答も表示する必要があります。私の問題は、最初の例では答えがないはずなので、次のようなものを使用できなかったということです:
= form_for @user do |f|
-#some code and then...
%table.table
- @user.answers.each do |answer|
= f.fields_for :answers, answer do |a|
%tr
%td= answer.question.name
%td=a.number_field :result
この場合、回答がないため、何も表示されません。答えがあったとしても、ユーザーにすべての質問を表示する必要があります。空の値で回答を事前に初期化することもできますが、空の値だけで一連のレコードを保持したくありません (これらの質問のほとんどは、ユーザーによって回答されることはありません)。もう1つのことは、質問には順序があり、ループでどのようにソートされるかわかりません@user.answers.each
(ええ、クエリを変更できるので、ソートできますが、何かを微調整しすぎます...単純?)。一般に、メイン ループは であり@questions.each
、 ではありません@user.answers.each
。
フィールドを手動で作成するなど、いくつかの厄介な方法でそれを行うことを考えてきましたが、レールがそれを行うためのクリーンな方法を持っていることを願っています. 誰かが以前にこのような問題に遭遇したことがありますか? それを行う方法は他にありませんが、これらすべてをカスタムヘルパーで作成しますか?. 前もって感謝します
アップデート
最後に、@saverioの回答のおかげで、次のように残しました。
%table.table
- @questions.each_with_index do |q, i|
%tr
%td= q.name
%td
- answer = @user.answers.detect{|a| a.question.try(:id) == q.id}
= number_field_tag "user[answers_attributes][#{i}][result]", (answer && answer.result)
= hidden_field_tag "user[answers_attributes][#{i}][id]", (answer && answer.id)
= hidden_field_tag "user[answers_attributes][#{i}][question_id]", q.id
コントローラーでは、次の行で、すべての空の値を消去するのに十分でした:
params[:user][:answers_attributes].delete_if{|k,v| v[:result].blank? && v[:id].blank?}