Module: StateTracking::InstanceMethods

Defined in:
lib/state_tracking.rb

Overview

Class Methods

Instance Method Summary collapse

Instance Method Details

#_state_tracking_dataObject



162
163
164
# File 'lib/state_tracking.rb', line 162

def _state_tracking_data
  @__state_tracking_data ||= self.state_tracking ? JSON.parse(self.state_tracking) : {}
end

#_state_tracking_record_state_change(state) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/state_tracking.rb', line 172

def _state_tracking_record_state_change(state)
  unless self.state || state == self.class.aasm.initial_state
    # Want to make sure that we record entering the initial state
    # in the history even if a subsequent state is being entered
    # before creating the instance.
    self.aasm.enter_initial_state
  end

  @_state_tracking_data_changed = true

  (_state_tracking_data['history'] ||= []) << {
    'state' => state.to_s,
    'time'  => Time.now.to_f,
    'meta' => {}
  }

  # We don't want to add stashed metadata to the initial state. Otherwise,
  # there will be duplicate metadata in the intial_state and the current
  # state. We will add initial_state metadata support at a later date
  if state != self.class.aasm.initial_state && @_state_tracking_pending_meta
    update_state_meta(@_state_tracking_pending_meta)
  end
end

#_state_tracking_saveObject



166
167
168
169
170
# File 'lib/state_tracking.rb', line 166

def _state_tracking_save
  if @_state_tracking_data_changed
    self.state_tracking = JSON.dump(_state_tracking_data)
  end
end

#_state_tracking_stash_meta(meta = {}) ⇒ Object



158
159
160
# File 'lib/state_tracking.rb', line 158

def _state_tracking_stash_meta(meta={})
  @_state_tracking_pending_meta = meta.is_a?(Hash) ? meta : nil
end

#state_at(time) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/state_tracking.rb', line 139

def state_at(time)
  unless time.is_a?(Date) || time.is_a?(Time) || time.is_a?(DateTime)
    raise ArgumentError, "invalid time: #{time}"
  end

  # Get the most recent state up to the time param
  state_obj = state_history.find_all { |state_obj|
    state_obj['time'] <= time.to_time.to_f
  }.last

  state_obj && state_obj['state']
end

#state_history(state_name = nil) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/state_tracking.rb', line 115

def state_history(state_name = nil)
  history = _state_tracking_data['history'] || []

  if state_name
    timestamp = nil

    # Find most recent time when the object was in the specified state.
    history.reverse_each do |record|
      if record['state'] == state_name.to_s
        timestamp = record['time']
        break
      end
    end

    timestamp
  else
    history
  end
end

#update_state_meta(meta = {}) ⇒ Object



152
153
154
155
156
# File 'lib/state_tracking.rb', line 152

def update_state_meta(meta={})
  state_history = _state_tracking_data['history'].last
  raise "No current state" unless state_history
  state_history['meta'].merge!(meta)
end

#was?(state_name) ⇒ Boolean

Returns:

  • (Boolean)


135
136
137
# File 'lib/state_tracking.rb', line 135

def was?(state_name)
  !state_history(state_name).nil?
end