为什么我在运行回调after_save时得到错误堆栈级别太深

时间:2012-11-22 15:30:05

标签: ruby-on-rails ruby-on-rails-3

我有2个型号:

  • GeneralExam有很多TopicQuestion
  • TopicQuestion属于GeneralExam,belongs_to主题

这是两个模型中的列:

  • GeneralExam:name,description,number_question
  • 主题问题: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"}

我错了什么?

2 个答案:

答案 0 :(得分:11)

你最后打电话给self.save。它正在开始另一个after_save回调。

如果你的rails版本是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 :(得分:0)

使用after_commit作为回调。它会正常工作,因为它不会循环。