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
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
.
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
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
update_column
is an ActiveRecord
function which does not run any callbacks, and it also does not run validation.
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.
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