Skip to content

Idempotent Callback Registration

the8472 edited this page Aug 30, 2012 · 1 revision

Scenario: A state-machine is assembled by modular code. Due to some reasons a module might be included twice.

How to add callbacks without registering them twice?

Since StateMachine::Callback does not have a getter for the methods it calls one has to define the callback in a uniquely identifiable way, i.e. the DSL cannot be used.

Solution (using Rails here)

module MyModule
  extend ActiveSupport::Concern

  CALLBACK = StateMachine::Callback.new :after, :from_state => :to_state, :do => :some_method

  included do
    callbacks = state_machines[:my_machine].callbacks[:after]
    callbacks << CALLBACK unless callbacks.include? CALLBACK
  end

  def some_method(object, transaction)
    # your callback code here
  end

end

Instantiating the callback only once allows for identity comparison and thus checking if the callback is already present in the registered callbacks of the state machine without inspecting the callback itself.

Clone this wiki locally