How to save a model without running callbacks in Rails

后端 未结 8 2410
青春惊慌失措
青春惊慌失措 2020-12-29 04:55

I need to calculate values when saving a model in Rails. So I call calculate_averages as a callback for a Survey class:

before_save         


        
相关标签:
8条回答
  • 2020-12-29 05:25

    I believe what you are asking for can be achieved with ActiveSupport::Callbacks. Have a look at set_callback and skip_callback.

    In order to "force callbacks to get called even if you made no changes to the record", you need to register the callback to some event e.g. save, validate etc..

    set_callback :save, :before, :my_before_save_callback
    

    To skip the before_save callback, you would do:

    Survey.skip_callback(:save, :before, :calculate_average). 
    

    Please reference the linked ActiveSupport::Callbacks on other supported options such as conditions and blocks to set_callback and skip_callback.

    0 讨论(0)
  • 2020-12-29 05:30

    Doesn't work for Rails 5

    Survey.skip_callback(:save, :before, :calculate_average) 
    

    Works for Rails 5

    Survey.skip_callback(:save, :before, :calculate_average, raise: false)
    

    https://github.com/thoughtbot/factory_bot/issues/931

    0 讨论(0)
  • 2020-12-29 05:34

    Rails 5.2.3 requiring an after party script to NOT trigger model events, update_column(column_name, value) did the trick:

    task.update_column(task_status, ReferenceDatum::KEY_COMPLETED)
    

    https://apidock.com/rails/ActiveRecord/Persistence/update_column

    0 讨论(0)
  • 2020-12-29 05:35

    update_column is an ActiveRecord function which does not run any callbacks, and it also does not run validation.

    0 讨论(0)
  • 2020-12-29 05:44

    hopefully this is what you're looking for.

    https://stackoverflow.com/a/6587546/2238259

    For your second issue, I suspect it would be better to inspect when this calculation needs to happen, it would be best if it could be handled in batch at a specified time where network traffic is at its trough.

    EDIT: Woops. I actually found 2 links but lost the first one, apparently. Hopefully you have it fixed.

    0 讨论(0)
  • 2020-12-29 05:45

    For Rails 3 ActiveSupport::Callbacks gives you the necessary control. You can reset_callbacks en-masse, or use skip_callback to disable judiciously like this:

    Vote.skip_callback(:save, :after, :add_points_to_user)
    

    …after which you can operate on Vote instances with :add_points_to_user inhibited

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