Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save a model without running callbacks in Rails

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 :calculate_averages 

However, occasionally (and initially I have 10k records that need this operation) I need to manually update all the averages for every record. No problem, I have code like the following:

Survey.all.each do |survey|   survey.some_average = (survey.some_value + survey.some_other_value) / 2.to_f   #and some more averages...   survey.save! end 

Before even running this code, I'm worried the calculate_averages is going to get called and duplicate this and probably even cause some problems with the way I'm doing things. Ok, so then I think, well I'll just do nothing and let calculate_averages get called and do its thing. Problem there is, first, is there a way to force callbacks to get called even if you made no changes to the record?

Secondly, the way averages are calculated it's far more efficient to simply not let the callbacks get called at all and do the averages for everything all at once. Is this possible to not let callbacks get called?

like image 969
at. Avatar asked Jan 27 '14 01:01

at.


People also ask

What are model callbacks in rails?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.

Does Update_attributes Skip Callbacks?

Update attributes in database without saving Callbacks are skipped.

What is around callback in rails?

In Rails, callbacks are hooks provided by Active Record that allow methods to run before or after a create, update, or destroy action occurs to an object. Since it can be hard to remember all of them and what they do, here is a quick reference for all current Rails 5 Active Record callbacks.


1 Answers

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.

like image 138
vee Avatar answered Sep 28 '22 06:09

vee