Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

ruby on rails - Prevent infinite loop when updating attributes within after_commit, :on => :create

I create an infinite callback loop when I need to update an attribute during an after_commit, :on => :create. It only occurs if I need to update an attribute of the object during this callback, though. Is there a way to prevent this? Can I somehow force a model to reload itself so it knows that it is performing an update rather than a 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the method update_column that will skip all callbacks of your model:

self.update_column(:filename, filename)

Or you could use the method update_all, wich follows the same behavior

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

And last but not least, my personal favorite:

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

This one makes it pretty clear that all callbacks are been ignored, what is very helpful


Also, as a different alternative, you coud use after_create instead of after_commit if you want to run the generate method only when a new record is saved


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...