Saving different Active Record classes in a single transaction
I’ve been getting in and out of rails development for some time now… and my biggest problem is finding documentation for simple things (I guess that people already know all the stuff, but I’m still getting up to speed).
So I decided to blog about one of those simple things… in case there is still someone who has not mastered Ruby on Rails.
When several models are saved in a single transaction in Rails, the usual case is that you want to rollback the transaction if any of them fails. This is done automatically if an exception is thrown.
However, you usually also want to display validation errors and not show the full rails trace to the user.
What the example does not show is how to accomplish this. Two options here:
- use save (no exclamation mark) and check the return value. If any of the saves return false, raise an ActiveRecord::RollbackException after your render or redirect.
- rescue from ActiveRecord::RecordInvalid and render or redirect there.
I think #2 is more elegant… but since I knew about it too late, my code uses #1.
begin transaction do first.save! second.save! third.save! fourth.save! end rescue ActiveRecord::RecordInvalid => invalid # do whatever you wish to warn the user, or log something end
Example is from this other blog post. I wish I’ve read it sooner!