Situation: A payment logging system. A user can accept multiple payments (cash or check) which get logged as ‘pending review’. The user then goes to a new page that shows a summary of all the pending payments, they verify all the pending payments and verify that the program’s total matches their total(on a calculator). Then they want a single button to accept all the pending payments.
Initial Implementation: Controller finds the clients pending payments and calls the service object PaymentApplication which provides some other complex logic before updating the payment as ‘applied’.
class PaymentsController < ApplicationController def apply_pending payments = @client.payments.pending return_value = false Payment.transaction do payments.each do |payment| pay_apply = PaymentApplication.new(payment) pay_apply.apply end return_value = true end end
Issue #1: Is this an improper way to use transactions? There’s gotta be a better way to do that, and should I be raising an active record rollback or something instead of that business with the ‘return_value’ variable?
Issue #2: What if another user from the same client adds more pending payments while user #1 is reviewing his payments? The current implementation applies all pending payments. How would you avoid that? Would you just include the payment ids in the view somehow and then pass them back to the controller apply action indicating the payment ids which should be accepted?