state_machine

Initializations

  • Initial values for state machine attributes are automatically assigned when a new object is created
  • This will not work if the class defines an initialize method without calling super
Examples
  class Vehicle
    state_machine :state, :initial => :parked do
      ...
    end
  end

  vehicle = Vehicle.new   # => #<Vehicle:0xb7c8dbf8 @state="parked">
  vehicle.state           # => "parked"

In the above example, no initialize method is defined. As a result, the default behavior of initializing the state machine attributes is used.

In the following example, a custom initialize method is defined:

  class Vehicle
    state_machine :state, :initial => :parked do
      ...
    end

    def initialize
    end
  end

  vehicle = Vehicle.new   # => #<Vehicle:0xb7c77678>
  vehicle.state           # => nil

Since the initialize method is defined, the state machine attributes never get initialized. In order to ensure that all initialization hooks are called, the custom method must call super without any arguments like so:

  class Vehicle
    state_machine :state, :initial => :parked do
      ...
    end

    def initialize(attributes = {})
      ...
      super()
    end
  end

  vehicle = Vehicle.new   # => #<Vehicle:0xb7c8dbf8 @state="parked">
  vehicle.state           # => "parked"

Because of the way the inclusion of modules works in Ruby, calling super() will not only call the superclass's initialize, but also initialize on all included modules. This allows the original state machine hook to get called properly.

If you want to avoid calling the superclass's constructor, but still want to initialize the state machine attributes:

  class Vehicle
    state_machine :state, :initial => :parked do
      ...
    end

    def initialize(attributes = {})
      ...
      initialize_state_machines
    end
  end

  vehicle = Vehicle.new   # => #<Vehicle:0xb7c8dbf8 @state="parked">
  vehicle.state           # => "parked"

You may also need to call the initialize_state_machines helper manually in cases where you want to change how static / dynamic initial states get set. For example, the following example forces the initialization of static states regardless of their current value:

  class Vehicle
    state_machine :state, :initial => :parked do
      state nil, :idling
      ...
    end

    def initialize(attributes = {})
      @state = 'idling'
      initialize_state_machines(:static => :force) do
        ...
      end
    end
  end

  vehicle = Vehicle.new   # => #<Vehicle:0xb7c8dbf8 @state="parked">
  vehicle.state           # => "parked"

The above example is also noteworthy because it demonstrates how to avoid initialization issues when nil is a valid state. Without passing in :static => :force, state_machine would never have initialized the state because nil (the default attribute value) would have been interpreted as a valid current state. As a result, state_machine would have simply skipped initialization.

results matching ""

    No results matching ""