0

I have a State Machine, in a Rails app (with ActiveRecord), defined with AASM and it has a lot of callbacks. Some of these callbacks contain repeated code. E.g, on every state change, we need to build and save a record and send a mail.

event :revision, after: :revision_event_callback do
  # ...
end

event :basic_submit, after: :basic_submit_event_callback do
  # ...
end

event :approve, after: :approve_event_callback do
  # ...
end

def revision_event_callback
  OrderStatusMailer.status_change_report(self, :revision)
  state_changes.build(transition: :revision)
end

def basic_submit_event_callback
  OrderStatusMailer.status_change_report(self, :basic_submit)
  state_changes.build(transition: :basic_submit)
  # ...
  # basic_submit-specific events
end

def approve_event_callback
  OrderStatusMailer.status_change_report(self, :approve)
  state_changes.build(transition: :approve)
end

Intead, I'd like to have one generic callback, and, for the events that need it, a specific in addition.

def event_callback(event_name)
  OrderStatusMailer.status_change_report(self, event_name)
  state_changes.build(transition: event_name)
end

def basic_submit_event_callback
  # basic_submit-specific events
end

Is this possible at all? And, quite important: how would that code have access to the name of the event that was triggered?

berkes
  • 26,996
  • 27
  • 115
  • 206

2 Answers2

2

How about doing this.

after_all_events : event_callback

and later define a method

 def event_callback(*args)
    # do stuff here
    after_callback = "after_#{current_event}"
    send(callback, *args) if respond_to?(callback)
 end
Arpan Lepcha
  • 176
  • 2
  • 4
0

It's possible. You can – in any callback like :after – request the current event which got triggered, like this:

def event_callback
  event_name = aasm.current_event # e.g. :revision or :revision!
  OrderStatusMailer.status_change_report(self, event_name)
  state_changes.build(transition: event_name)
end
alto
  • 609
  • 4
  • 8
  • And is `event_callback` a magic method that will be added to the calback-chain by default? Or do I still need to add it as `after: :event_callback` in the event-declarations? – berkes Mar 31 '15 at 09:40
  • No, that's your method from above. You still need to declare it to be called as :after callback (using event :revision, after: :event_callback do...) – alto Apr 01 '15 at 10:10