Last Updated: February 25, 2016
·
472
· wojtekkruszewsk

Skip AR callbacks

This old question still comes up a lot: I have this callback that sends email, makes coffee and takes $10 from my credit card. I'm creating this object in a loop in a test and I'm out of money.

Usually... shouldn't do this in callbacks anyway, try creating separate method like Project.submit_and_do_stuff(attrs). Or try service objects.

Having said that, you can reach directly into ActiveRecord persistence guts:

def lol_insert(record)
   record[:created_at] ||= Time.zone.now if record.respond_to?(:created_at=)
   record[:updated_at] ||= Time.zone.now if record.respond_to?(:updated_at=)
   ActiveRecord::Persistence.instance_method(:create_record).bind(record).call
   record
end

lol_insert( ModelWithLottaCallbacks.new )

This also skips other modules mixed into AR::Base, like automatic timestamps, hence we're filling them by hand.

Trick tested in Ruby 2.1.1 and Rails 4.1.

For updating record AR exposes neat update_columns method.