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?

[email protected] 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,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Feb 9, 8:14 pm, “[email protected][email protected] wrote:

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.

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.

[email protected] 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,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]