0

私は2つのモデルを持っています:

  • GeneralExam には多くの TopicQuestion があります
  • TopicQuestion は GeneralExam に属し、belongs_to トピック

これは 2 つのモデルの列です。

  • GeneralExam: 名前、説明、number_question
  • TopicQuestion: general_exam_id、topic_id、number_question

TopicQuestion の各トピックの number_question を加えて、一般試験の合計問題数を計算したいと思います。だから私はこのような方法を書きます:

class GeneralExam < ActiveRecord::Base

  has_many :topic_questions, dependent: :destroy

  validates :number_question, numericality: { only_integer: true, greater_than: 0 }, on: :save

  after_save :calc_number_question

  private

  def calc_number_question
    number_question = 0
    self.topic_questions.each do  |tq|
      number_question += tq.number_question
    end
    self.number_question = number_question
    self.save
  end
end

しかし、提出するとエラーが発生します:

SystemStackError in GeneralExamsController#create
stack level too deep

これは私のパラメータです:

{"utf8"=>"✓",
 "authenticity_token"=>"VyojDMOltc5wOJMDf4gtDM6lEk6soTZl/EaY9qrCRyY=",
 "general_exam"=>{"course_id"=>"1",
 "name"=>"dada",
 "description"=>"dada",
 "semester_id"=>"1",
 "duration"=>"1",
 "topic_questions_attributes"=>{"0"=>{"_destroy"=>"false",
 "topic_id"=>"15",
 "number_question"=>"15"},
 "1"=>{"_destroy"=>"false",
 "topic_id"=>"13",
 "number_question"=>"6"},
 "2"=>{"_destroy"=>"false",
 "topic_id"=>"Choose a topic",
 "number_question"=>""},
 "3"=>{"_destroy"=>"false",
 "topic_id"=>"Choose a topic",
 "number_question"=>""},
 "4"=>{"_destroy"=>"false",
 "topic_id"=>"Choose a topic",
 "number_question"=>""}}},
 "commit"=>"Create General exam"}

私は何を間違っていますか?

4

2 に答える 2

11

あなたself.saveは最後に電話しました。別のafter_saveコールバックを開始しています。

Rails のバージョンが 3.2.1 以降の場合は、使用できます

update_column :number_question, number_question

コールバックをスキップします。

オフトピック:

あなたはそれを書き直すことができます

number_question = 0
self.topic_questions.each do  |tq|
  number_question += tq.number_question
end

なので

number_question = self.topic_questions.inject(0) { |sum, tq| sum + tq.number_question }
于 2012-11-22T15:44:19.697 に答える
0

コールバックとして使用after_commitします。それ以降はループしません。

于 2013-12-29T01:20:04.187 に答える