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

后端 未结 3 1032
太阳男子
太阳男子 2020-12-20 15:02

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

相关标签:
3条回答
  • 2020-12-20 15:23

    It's a bug, see the Github issue https://github.com/rails/rails/issues/16286

    0 讨论(0)
  • 2020-12-20 15:37

    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

    0 讨论(0)
  • 2020-12-20 15:45

    The problem will be update_attributes will initiate the after_commit callback you've used

    As mentioned by Rafael, you'd either need to use a callback not triggered by update_attributes, or use an update method which negates callbacks:


    update_column does not initiate callbacks - self.update_column(filename: filename)


    after_create only fires when you create a record (not update) - after_create :generate

    0 讨论(0)
提交回复
热议问题