1

I am using aasm statemachine. I have the below event. What this does is changes the state from order_created to payment_response_received. So after changing this I want to call a method verify_payment_response(data). I can make this state change by calling @booking.move_to_payment_response_received! , but how can I pass parameters for use in the after callback?

event :move_to_payment_response_received do
  after_commit do
         self.verify_payment_response(data) #How can I pass this data param from my controller
  end
  transitions from: :order_created, to: :payment_response_received
end
Abhilash
  • 2,864
  • 3
  • 33
  • 67
  • What is the point of verifying the data in the state machine after the commit? Even if the data is not valid the event was fired? Should the data be verified before firing the event or as part of a validation while the event happens? Please show your controller method and the `verify_payment_response` method too. – spickermann Oct 15 '17 at 06:33
  • @spickermann I am receiving the payment_response from 2 sources. One from client browser js and other from a webhook directly from pg. So both I dont have any control. I want to only call the `verify_payment_response(data)` only once. So whichever response comes first will be used to `verify_payment_response(data)`. Also if the signature validation fails for some reason the `verify_payment_response` method makes an api call(background worker) to payment_gateway to check the status directly. So to prevent this from happening two times added the payment_response_received state – Abhilash Oct 15 '17 at 07:00
  • @spickermann the controller only have this `@booking.move_to_payment_response_received!` in an `if` clause.. The verify_payment_response can be invoked by 2 methods.(webhook & post request from js in client browser). I dont know which one will fire first. But which ever one comes first I want to use that. So if the state changes to payment_response_received the second one will fail and wont call verify_payment_response again and thats the intention of this approach. – Abhilash Oct 15 '17 at 07:10

2 Answers2

4

You can assign the data to a local variable before firing the event:

# in your model

attr_accessor :payment_response_data

event :move_to_payment_response_received, :after_commit => :verify_payment_response do
  transitions from: :order_created, to: :payment_response_received
end

private

def verify_payment_response
  data = payment_response_data

  # already existing code to verify `data`
end

And use this in your controller like this:

@booking.payment_response_data = data
@booking.move_to_payment_response_received!
spickermann
  • 100,941
  • 9
  • 101
  • 131
1
event(
  :move_to_payment_response_received, 
  after_commit: ->(data) { verify_payment_response(data) }
) { transitions from: :order_created, to: :payment_response_received }

Then call the event as: @booking.move_to_payment_response_received!(data)

Elliott de Launay
  • 1,027
  • 13
  • 31