Problem with before_* callbacks being wrapped in transaction

I am upgrading a 2.1 Rails app and ran into a problem with the new way that before_* callbacks are being wrapped in a transaction.

I have a model that has a before_create callback which charges the customers credit card. If the transaction is successful it returns true, and if not, false so that the record is not saved. In addition, I have a Cclog audit entry that is created regardless if the transaction is successful or not. This way I keep an audit trail.

This worked fine and well until somewhere in the 2.2/2.3 version of rails. Now the entire before_create callback is wrapped in a transaction which means that my Cclog object gets rolled back if the transaction is not successful and returns false. So I cannot keep an audit trail of unsuccessful credit card charges.

Is there a way to temporarily disable the transactional nature or the callbacks? The only way I can see getting this to work is moving the transaction/Cclog creation logic into a charge!() method, and making sure to call that method from my controller after it is already saved.

Any suggestions?

iwarshak@stripey.net wrote:

I am upgrading a 2.1 Rails app and ran into a problem with the new way that before_* callbacks are being wrapped in a transaction.

I have a model that has a before_create callback which charges the customers credit card. If the transaction is successful it returns true, and if not, false so that the record is not saved. In addition, I have a Cclog audit entry that is created regardless if the transaction is successful or not. This way I keep an audit trail.

This worked fine and well until somewhere in the 2.2/2.3 version of rails. Now the entire before_create callback is wrapped in a transaction which means that my Cclog object gets rolled back if the transaction is not successful and returns false. So I cannot keep an audit trail of unsuccessful credit card charges.

Is there a way to temporarily disable the transactional nature or the callbacks? The only way I can see getting this to work is moving the transaction/Cclog creation logic into a charge!() method, and making sure to call that method from my controller after it is already saved.

Any suggestions?

Perhaps you could use a savepoint.

But check the credit card companies' regulations; I seem to recall that keeping a log of unsuccessful charges is prohibited...

Best,

use save_without_transactions ?

Fred

Won't this savepoint also be rolled back?

Also, I am not storing any credit card numbers, cvv, etc. Basically the last 4 digits, decline code, etc.

Please quote when replying.

iwarshak@stripey.net wrote:

Won't this savepoint also be rolled back?

Why don't you try it and find out?

Also, I am not storing any credit card numbers, cvv, etc. Basically the last 4 digits, decline code, etc.

Check your merchant agreement. I'm no expert, but I'm not sure this is allowed.

Best,