1

「正しい」ブール列を持つ質問に属する回答モデルがあります。理想的には、質問の正解は 1 つだけです (stackoverflow システムによく似ています)。

ビューで「正しい」ブール値を切り替えるメソッドを使用する次のコントローラー+モデルコードがありtoggle_correctます(すべてうまく機能します)。

新しい回答を作成しようとするとone_correct_answer、正しい列がデフォルトに設定されていても検証エラーが発生します: 移行で false に設定され、アプリケーション POST トレースで値が 0 (false) に設定されます

この検証で問題ごとに 1 つの正解のみが許可され、新しい回答オブジェクトの作成が中断されないように、コードを修正するにはどうすればよいですか?

answer.rb

validate :one_correct_answer

  def one_correct_answer
    answers = self.question.answers.map(&:correct)
    errors.add(:user_id, "You can't have more than 1 correct answer #{answers}") if answers & [true]
    logger.debug("Answers array #{answers}")
  end

def toggle_correct(attribute)
    toggle(attribute).update_attributes({attribute => self[attribute]})
  end 

answer_controller.rb

def correct 
    @answer = Answer.find(params[:id])
    if @answer.toggle_correct(:correct)
    respond_to do |format|
      format.html { redirect_to :back, notice: "Answer submitted" }
      format.js
      end
    end
  end

_answer.html.erb

<div id="correct_answer_<%= answer.id %>" class="<%= answer.correct == true ? 'green-tick' : 'default-tick' %>">
    <% if answer.question.user == current_user %>
        <%= link_to "✓", correct_answer_path(answer), id: "tick", class: "correct_#{answer.id}", remote: true, method: :put %>
    <% else %>
        <% if answer.correct == true %>
           <div id="tick", class='correct_<% answer.id %>'> ✓&lt;/div>
        <% end %>
    <% end %>
</div>
4

2 に答える 2

1

あなたの問題はおそらくここにあります:

errors.add(:user_id, "You can't have more than 1 correct answer #{answers}") if answers & [true]

answers & [true]は常に配列を返します (answersは配列であるため)。空の配列は Ruby では真の値です。

それらが偽の値であったとしても、あなたの条件は機能しません。なぜなら、正しい答えは 1 つでなければならず、あなたの条件は何もないことをチェックするからです。

私はこの条件を使用します:

self.question.answers.count(&:correct) <= 1
于 2013-06-03T06:43:50.383 に答える
1

失敗する理由は、質問に関連付けられた回答が正しい場合にエラーを追加しているためです。そして、保存しようとしている答えが正しいかどうかに関係なく、これをテストします。したがって、最初にすべきことは、次のように、保存しようとしている答えが実際に正しい場合にのみ、正しい答えがあるかどうかを確認することです。

validate :one_correct_answer, if: :correct?

このように、メソッド one_correct_answer は、現在の回答が正しい場合にのみ検証されます。

ただし、まだ 1 つの追加の問題があります。保存しようとしている回答が正しい場合、メソッドが呼び出され、正しい回答がある場合はエラーが追加されます...現在の回答もその関連付けにリストされている必要があるため、おそらくそうなるでしょう. したがって、あなたがしたいことは、正しい追加の答えがあるかどうかを確認することです。

したがって、最終的には、代わりに次のように検証することになるでしょう。

validates_uniqueness_of :correct, scope: :question_id, if: :correct?

これにより、question_id 列と正しい列の一意の組み合わせが検証されますが、正しい列が true である場合のみ検証されます。これにより、問題ごとに複数の偽の列を持つことができますが、真の正しい列は 1 つだけです。

于 2013-06-03T06:41:16.787 に答える