2012-11-22 24 views
0

運行回調時,我有2個型號:爲什麼我得到錯誤堆棧層次過深after_save的

  • GeneralExam有許多TopicQuestion
  • TopicQuestion屬於GeneralExam,belongs_to的主題

這是在列兩種型號:

  • 一般檢查:名稱,說明,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"} 

什麼我錯了嗎?

回答

11

您最後稱爲self.save。它正在啓動另一個after_save回調。

如果您的軌道版本是3.2.1或更高版本可以使用

update_column :number_question, number_question 

跳過回調。

offtopic:

你可以把它改寫

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 } 
+1

謝謝,我發現了另一種計算方法,我使用sum方法:'number_question = TopicQuestion.sum(:number_question,conditions:{general_exam_id:self.id})' – Thanh

+0

'update_column'在rails 3.1及更高版本中工作。我只是用它來解決類似的問題。 – emkman

0

使用after_commit作爲回調。它會正常工作,因爲它不會循環。