Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Rails' active record, is there another way to get a rollback without raising an exception?

I'm writing testing and am bothered by the fact that I have to raise exceptions to get rollbacks.

raise ActiveRecord::Rollback

The reason why I am bothered by this is because I need to rollback to keep my database clean for the next test run. There was no exceptional event.

This goes against the idea of exceptions should not be expected. Besides for that exceptions are costly.

So, is there another way to rollback or are my concerns not sound (if so please explain why)?

I forgot to mention my app is a Sinatra app using ActiveRecord and mini test.

like image 561
l__flex__l Avatar asked Nov 10 '22 02:11

l__flex__l


1 Answers

I think your concerns are sound, generally. In most cases, exceptions are costly and should not be expected.

But, according to the documentation for ActiveRecord::Rollback, this exception is somewhat unique. It is meant to "distinguish a deliberate rollback from other exceptional situations".

To quote from the docs:

ActiveRecord::Transactions::ClassMethods#transaction uses this exception to distinguish a deliberate rollback from other exceptional situations. Normally, raising an exception will cause the transaction method to rollback the database transaction and pass on the exception. But if you raise an ActiveRecord::Rollback exception, then the database transaction will be rolled back, without passing on the exception.

If Rails specifically uses it this way, there really isn't a reason not to use it for this (or any other relevant) purpose.

With this being said, many people seem to prefer the simplicity of something like Rails' transactional fixtures or database cleaner for your use case, as pointed out by Sergio and Dan in the comments, instead of creating a custom solution.

like image 68
Brad Werth Avatar answered Nov 15 '22 04:11

Brad Werth