4

配列["Yes"、true]がどこから来たのかはわかりません。私はこのような2つのモデルを持っています:

GeneralExam has_many topic_questions

TopicQuestion belongs to general_exam, belongs_to topic

TopicQuestionには、general_exam_id、topic_id、number_questionの列があり、一般試験の各トピックの番号の質問を格納します。

新しい一般試験を作成するためのネストされたフォームを作成しました。動的選択を作成したフォームで、ユーザーがドロップダウンリストからコースを選択すると、ユーザーが選択したコースのトピックを表示する他のドロップダウンリストがあります。

これは、動的選択用のJavaScriptコードです。

<% content_for :head do %>
  <script type="text/javascript">
    $(document).ready(function() {
      $('#general_exam_course_id').change(function () {
        $.ajax({
          type: "POST",
          url: "<%= update_topics_general_exams_path %>",
          data: { course_id: $('#general_exam_course_id').val() },
          dataType: "script"
        });
      });
    </script>
<% end %>

#general_exam_course_id選択したコースのドロップダウンリストのIDです。一般的な試験コントローラーでupdate_topics_general_exams_pathの私の行動へのルートです、これは私の行動です:updateupdate

  def update_topics
    @course = Course.find(params[:course_id])
    @topics = @course.topics
  end

私も持っていupdate_topics.js.erbます:

$('div#topic_questions select').html("<%= j options_from_collection_for_select(@topics, 'id', 'name') %>");

のドロップダウンリストは、アクションから値div#topic_questions を取得し(私はそう思います)、それを表示します。私が新しい一般試験を作成するとき、それは大丈夫です。しかし、リンクを押すと、理由と場所がわからないエラーが表示されます。@topicsupdate_topicsEdit

NoMethodError in General_exams#edit
undefined method `name' for ["Yes", true]:Array

Extracted source (around line #3):

1: <div class="row">
2:  <div class="span6"><%= remove_child_link "Remove below topic", f %></div><br><br>
3:  <div class="span3"><%= f.association :topic, collection: @topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %></div>
4:  <%= f.input :number_question, placeholder: 'Number of questions', label: false, style: 'display: inline' %>
5: </div>

私のedit行動には次のものしかありません:@general_exam = GeneralExam.find(params[:id])topic一般試験の連想フィールドに配列が表示される理由がわかりません["はい"、true]。私はそれを持っていません、それをどこにも定義しません、なぜ私が一般試験を編集するときにそれが来るのですか?

アップデート

私が削除label_method: :name, value_method: :idした場合:

<%= f.association :topic, collection: @topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>

このページはエラーではありませんが、ドロップダウンリストにはYes, No、試験用に作成したトピックの名前ではなく、selectに値があります。フォームは各トピックの番号の質問を取得できますが、トピックの名前を取得することはできません。

私が作成するとき:

画像

私が編集するとき:

画像

私はこれを見つけましたconfig/locales/simple_form.en.yml

en:
  simple_form:
    "yes": 'Yes'
    "no": 'No'

これは問題ですか?

更新:新しいアクションで@topicsを渡さないでください。ただし、コースがまだ選択されていない場合でも、新しいページに残ります。

私の新しい行動:

  def new
    @general_exam = GeneralExam.new
    5.times { @general_exam.topic_questions.build }
    #@topics = Topic.all
  end

上記の抽出ソースと同様に、以下のコードを新規に編集します(同じフォームを使用)。

<%= f.association :topic, collection: @topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>

したがって、@ topicsは渡しませんが、新しいページに移動すると、トピックのドロップダウンリストにYes, No値が表示されます。

4

2 に答える 2

2

わかりました、チャットのようなコメントの時間は終わりました:)(システムはチャットルームに移動するように提案しました)。simple_form の関連付けでコレクションをインラインで渡しているように見える解決策:

<%= f.association :topic, collection: @topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>

になります:

<%= f.association :topic, collection: Topic.limit(1), prompt: "Choose a topic", label: false %>

今のところうまくいくと思います。

于 2012-11-22T23:22:55.590 に答える
1

クエリを割り当てて@topicsビューに渡すことで正しいアイデアを得ることができました...しかし、間違ったアクションに入れ、正しいビューに渡していません:

def update_topics
  @course = Course.find(params[:course_id])
  @topics = @course.topics
end

-

あなたがすべきこと:

更新アクションには NOupdate viewがないため、次の 2 行を配置する必要があります。

@course = Course.find(params[:course_id])
@topics = @course.topics

newあなたの行動とあなたのedit行動の両方で

次に、元の simple_form コードを使用することができます。これは、元は正しかったです。

<%= f.association :topic, collection: @topics, 
                  label_method: :name, value_method: :id, 
                  prompt: "Choose a topic", label: false 
%>

または、コントローラーで @topics をSKIPして、ビューに次のコードを追加することもできます。

新しいビュー

<%= f.association :topic, collection: Topics.all, 
                  label_method: :name, value_method: :id, 
                  prompt: "Choose a topic", label: false 
%>

ビューを編集

<%= f.association :topic, collection: Course.find(params[:course_id]).topics, 
                  label_method: :name, value_method: :id, 
                  prompt: "Choose a topic", label: false 
%>

違いに 注意してください:

  • あなたのnew見解では、ユーザーに可能なすべてのトピックを表示してもらいたいと思います。
  • あなたのeditビューでは、このコースのトピックを彼らに見てもらいたいだけですよね?

-

なぜそれが起こったのか:

  1. 以前にコレクションを渡していなかったので、ドロップダウンのラベル/表示値として使用する simple_form の「名前」メソッド/列がなかったため、エラーメッセージに関するエラーメッセージが表示されましたArray ["Yes",true]

  2. オプションを削除した場合、label_method: :name, value_method: :id,おそらくドロップダウンの行に期待していたのと同じ数の選択肢が表示されたでしょうが、コースのトピック名のリストの代わりに、Topic オブジェクトのリストが表示されたはずです (次のようなもの):

    #<Topic::xxxx>
    #<Topic::xxxx>
    ...
    #<Topic::xxxx>
    
  3. また、コレクションを提供しない場合は、見つけた構成ファイルごとに simple_form のデフォルトである 2 つの yes/no 値しか得られません ( config/locales/simple_form.en.yml)。

  4. お察しのとおり、これが最終的に使用した理由です...

    <%= f.association :topic, collection: 
                      Topic.limit(1), 
                      prompt: "Choose a topic", 
                      label: false 
    %>
    

    ...回避策として「うまくいきました」 --適切なクエリを*実行*し、それをsimple_formに提供したが、結果をテーブルの*最初の*トピックのみに制限したため(順序付け/ソートなし) )

少なくとも、これは私が学んだ/経験したことです。チッ!

于 2013-08-26T16:21:35.557 に答える