“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey (contact@robl.me)
Senior Software Engineer, Brighton, UK

saving ActiveRecord objects without callbacks

Just found a broken test that I just couldn’t fathom, its testing an action that occurs within in an callback. We need to set up an object in the correct state to be inline without our live database. new_salted_password is set when the record is next saved, so it is important that it is nil before we call our method.

p = Thing.create(:user => 'robl', :password => '12345', :password_confirmation => '12345')
p.write_attribute(:new_salted_password, nil)

This has worked fine for sometime. Write attribute appears to skip callbacks. I could have written the following as the callback actually occurs within an after_validation callback and the validation step is skipped here.

p = Thing.create(:user => 'robl', :password => '12345', :password_confirmation => '12345')
p.new_salted_password = nil
p.save(false)

However, I needed to move the callback method within the before_save callback sequence so both of the above methods failed both save(false) and write_attribute saves the object. After much hunting it appears the solution is to the use the private method update_without_callbacks. There is also a create_without_callbacks method.

p = Thing.create(:user => 'robl', :password => '12345', :password_confirmation => '12345')
p.new_salted_password = nil
p.send(:update_without_callbacks)