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.
Want to receive useful tips, information about new Ruby gems and articles on a daily basis? Make sure you follow me and say hello!
Rails transaction creation
You have to simply call
.transaction on your model class, model instance or more general 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.