Rails transactions overview

Ruby on Rails / Active Record

The transaction is a set of smaller actions such as database records creation, very often combined with an external API call. When you build a guestbook application and some of your guests want to add a record and creation fails it’s not a disaster but imagine a case when you want to charge your user in an online store and something goes wrong at some point.

When something goes wrong in a chain of actions you probably want to revert previous changes and start again by asking a user to input information and start the process one more time. You have to take care of deleting all records created during the failed process but you can also use Rails transactions.

Rails transaction creation

You have to simply call .transaction on your model class, model instance or more generally on ActiveRecord::Base – just pick the most suitable way for given case. A transaction is bound to the database connection, not the model instance.

Order.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end
@order.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end
ActiveRecord::Base.transaction do
  @order.charge_credit_card!
  @user.order_histories.create!(@order)
end

When something goes wrong

It’s very important to remember that we can rollback transaction only by raising an error. If you are using find_by methods inside a transaction block you should start using find_by! to ensure that when something would go wrong your application would throw an error. After transaction rollback error would be raised outside of transaction block so be ready to catch it.

If you want to rollback transaction silently then simply raise ActiveRecord::Rollback error inside of your transaction block.

There is more

This article is an introduction to the Rails transactions. It’s also worth to mention about nested transactions and callbacks and I will do it soon.