Inspecting model callback chains
If you need to look at the list of methods that are called upon certain events (like before/after saving etc), do this:
Model._save_callbacks.select {|cb| cb.kind == :before}.map{ |c| c.instance_variable_get :@filter }
Rails 2
User.after_save_callback_chain
To look at the method names only, you could do something like that:
User.after_save_callback_chain.collect(&:method)
Related cards:
Save ActiveRecord models without callbacks or validations (in Rails 2 and Rails 3)
Rails 2
You can use
record.send(:update_without_callbacks)
or
record.send(:create_without_callbacks)
This can be used as a lightweight alternative to machinist's make
or FactoryGirl's create
, when you just need objects...
Testing ActiveRecord callbacks with RSpec
Our preferred way of testing ActiveRecord is to simply create/update/destroy the record and then check if the expected behavior has happened.
We used to bend over backwards to avoid touching the database for this. For this we used a lot of stubbi...
Order of the state_machine callback chain
- before transition
- before validation
- after validation
- before save
- after save
- after transition
Aborting the callback chain
See [Cancel the ActiveRecord callback chain](https://makandracards.com/makandr...
Pitfall: ActiveRecord callbacks: Method call with multiple conditions
In the following example the method update_offices_people_count
won't be called when office_id
changes, because it gets overwritten by the second line:
after_save :update_offices_people_count, :if => :office_id_changed? # is overwritt...
Apply a new callback to existing records
So you added a new callback to your model that (e.g.) caches some data when it is saved. Now you need to run that callback for the 10000 existing records in the production database. You have two options here:
- Write a clever migration, possibly...
Cancelling the ActiveRecord callback chain
What | Rails version | Within before_*
|
Within after_*
|
---|---|---|---|
Cancel later callbacks | Rails 1-4 | `re... |
Good real world example for form models / presenters in Rails
We have often felt the pain where our models need to serve too many masters. E.g. we are adding a lot of logic and callbacks for a particular form screen, but then the model becomes a pain in tests, where all those callbacks just get in the way. O...
Testing state_machine callbacks without touching the database
You should test the callback methods and its correct invocation in two separate tests. Understand the ActiveRecord note before you move on with this note.
Say this is you...
Rails < 5: How to get after_commit callbacks fired in tests
If you use transactional_fixtures
or the database_cleaner gem with strategy :transaction
, after_commit
callbacks will not be fired in your tests.
Rails 5+
Rails 5 has a [fix](https://...
Touch records without running callbacks
ActiveRecord comes with a method touch
which sets the updated_at
timestamp to the current time. Unfortunately it also runs callbacks (and hence validations) on the receiving record, so i...