Module: StateMachines::Integrations::ActiveModel

Defined in:
lib/state_machines/integrations/active_model/observers.rb,
lib/state_machines/integrations/active_model/observers/version.rb,
lib/state_machines/integrations/active_model/observers/observer_update.rb

Defined Under Namespace

Modules: Observer, Observers Classes: ObserverUpdate

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.matching_ancestorsObject

Classes that include ActiveModel::Observing will automatically use the ActiveModel integration.



11
12
13
# File 'lib/state_machines/integrations/active_model/observers.rb', line 11

def self.matching_ancestors
  [::ActiveModel, ::ActiveModel::Observing, ::ActiveModel::Validations]
end

Instance Method Details

#add_callback(type, options, &block) ⇒ Object



60
61
62
63
64
65
# File 'lib/state_machines/integrations/active_model/observers.rb', line 60

def add_callback(type, options, &block)
  options[:terminator] = callback_terminator
  @callbacks[type == :around ? :before : type].insert(-2, callback = StateMachines::Callback.new(type, options, &block))
  add_states(callback.known_states)
  callback
end

#add_default_callbacksObject

Adds a set of default callbacks that utilize the Observer extensions



16
17
18
19
20
# File 'lib/state_machines/integrations/active_model/observers.rb', line 16

def add_default_callbacks
  callbacks[:before] << StateMachines::Callback.new(:before) { |object, transition| notify(:before, object, transition) }
  callbacks[:after] << StateMachines::Callback.new(:after) { |object, transition| notify(:after, object, transition) }
  callbacks[:failure] << StateMachines::Callback.new(:failure) { |object, transition| notify(:after_failure_to, object, transition) }
end

#after_initializeObject

Initializes class-level extensions and defaults for this machine



68
69
70
71
# File 'lib/state_machines/integrations/active_model/observers.rb', line 68

def after_initialize
  super()
  add_default_callbacks
end

#notify(type, object, transition) ⇒ Object

Notifies observers on the given object that a callback occurred involving the given transition. This will attempt to call the following methods on observers:

  • #{type}_#{qualified_event}from#{from}to#{to}

  • #{type}_#{qualified_event}from#{from}

  • #{type}_#{qualified_event}to#{to}

  • #{type}_#{qualified_event}

  • #{type}transition#{machine_name}from#{from}to#{to}

  • #{type}transition#{machine_name}from#{from}

  • #{type}transition#{machine_name}to#{to}

  • #{type}transition#{machine_name}

  • #{type}_transition

This will always return true regardless of the results of the callbacks.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/state_machines/integrations/active_model/observers.rb', line 37

def notify(type, object, transition)
  name = self.name
  event = transition.qualified_event
  from = transition.from_name || 'nil'
  to = transition.to_name || 'nil'

  # Machine-specific updates
  ["#{type}_#{event}", "#{type}_transition_#{name}"].each do |event_segment|
    ["_from_#{from}", nil].each do |from_segment|
      ["_to_#{to}", nil].each do |to_segment|
        object.class.changed if object.class.respond_to?(:changed)
        object.class.notify_observers('update_with_transition', ObserverUpdate.new([event_segment, from_segment, to_segment].join, object, transition))
      end
    end
  end

  # Generic updates
  object.class.changed if object.class.respond_to?(:changed)
  object.class.notify_observers('update_with_transition', ObserverUpdate.new("#{type}_transition", object, transition))

  true
end