更新after_commit中的属性时防止无限循环,:on => :创建

时间:2014-03-21 19:00:26

标签: ruby-on-rails activerecord ruby-on-rails-4 callback

当我需要在after_commit, :on => :create期间更新属性时,我创建了一个无限回调循环。但是,只有在我需要在此回调期间更新对象的属性时才会发生这种情况。有办法防止这种情况吗?我可以以某种方式强制模型重新加载自己,因此它知道它正在执行更新而不是创建吗?

class Doc < ActiveRecord::Base
  after_commit :generate, :on => :create

  ...

  def generate
    # some logic here that requires this model to be saved in the db

    self.update_attributes(:filename => filename) # Infinite loop begins here.
  end
end

3 个答案:

答案 0 :(得分:20)

您可以使用将跳过模型的所有回调的方法update_column

self.update_column(:filename, filename)

或者你可以使用方法update_all,它遵循相同的行为

self.class.where('id = ?', self.id).update_all(:filename => filename)

最后但并非最不重要的,我个人的最爱:

self.filename = filename
self.send(:update_without_callbacks)

这个很清楚,所有的回调都被忽略了,这是非常有用的


此外,作为另一种选择,如果您只想在保存新记录时运行after_create方法,则可以使用after_commit代替generate

答案 1 :(得分:1)

问题是update_attributes将启动您已使用过的after_commit回调

如Rafael所述,您需要使用不是由update_attributes触发的回调,或使用否定回调的更新方法:


update_column 无法发起回调 - self.update_column(filename: filename)


after_create 仅在您创建记录(而不是更新)时触发 - after_create :generate

答案 2 :(得分:0)

这是一个错误,请参阅Github问题https://github.com/rails/rails/issues/16286