class SimpleStates::Event

Constants

MSGS

Public Instance Methods

call(obj, data, opts) { || ... } click to toggle source
# File lib/simple_states/event.rb, line 8
def call(obj, data, opts)
  return false if not ordered?(obj, data) or not applies?(obj, data)

  run_callbacks(:before, obj, data)
  set_attrs(obj, data)
  yield
  obj.save! if opts[:save]

  raise_unknown_state(obj, data) unless known_state?(obj)
  run_callbacks(:after, obj, data)
  obj.save! if opts[:save]
  true
end
reset(obj) click to toggle source
# File lib/simple_states/event.rb, line 22
def reset(obj)
  Array(opts[:to]).each { |state| set_attr(obj, :"#{state}_at", nil) }
end

Private Instance Methods

applies?(obj, data) click to toggle source
# File lib/simple_states/event.rb, line 51
def applies?(obj, data)
  result = opts[:if].nil? || send_methods(opts[:if], obj, data)
  result and opts[:unless].nil? || !send_methods(opts[:unless], obj, data)
end
has_timestamp?(obj, key) click to toggle source
# File lib/simple_states/event.rb, line 42
def has_timestamp?(obj, key)
  key.to_s.end_with?('_at') && obj.respond_to?(key) && obj.send(key)
end
known_state?(obj) click to toggle source
# File lib/simple_states/event.rb, line 73
def known_state?(obj)
  obj.class.states.include?(obj.state)
end
ordered?(obj, data) click to toggle source
# File lib/simple_states/event.rb, line 46
def ordered?(obj, data)
  states = obj.class.states
  states.index(obj.state).to_i <= states.index(target_state(data)).to_i
end
raise_invalid_state(data) click to toggle source
# File lib/simple_states/event.rb, line 77
def raise_invalid_state(data)
  raise Error, MSGS[:invalid_state] % [data[:state], Array(opts[:to])]
end
raise_unknown_state(obj, data) click to toggle source
# File lib/simple_states/event.rb, line 81
def raise_unknown_state(obj, data)
  raise Error, MSGS[:unknown_state] % [obj.state, obj, name, obj.class.states]
end
run_callbacks(type, obj, data) click to toggle source
# File lib/simple_states/event.rb, line 28
def run_callbacks(type, obj, data)
  send_methods(opts[type], obj, data)
end
send_method(name, obj, data) click to toggle source
# File lib/simple_states/event.rb, line 69
def send_method(name, obj, data)
  obj.send(name, *[self.name, data].slice(0, obj.method(name).arity.abs))
end
send_methods(names, obj, data) click to toggle source
# File lib/simple_states/event.rb, line 63
def send_methods(names, obj, data)
  Array(names).inject(false) do |result, name|
    result | send_method(name, obj, data)
  end
end
set_attr(obj, key, value) click to toggle source
# File lib/simple_states/event.rb, line 38
def set_attr(obj, key, value)
  obj.send(:"#{key}=", value) if obj.respond_to?(:"#{key}=") and not has_timestamp?(obj, key)
end
set_attrs(obj, data) click to toggle source
# File lib/simple_states/event.rb, line 32
def set_attrs(obj, data)
  attrs = { :"#{target_state(data)}_at" => Time.now.utc }.merge(data)
  attrs.each { |key, value| set_attr(obj, key, value) }
  obj.state = target_state(data)
end
target_state(data) click to toggle source
# File lib/simple_states/event.rb, line 56
def target_state(data)
  to = Array(opts[:to])
  return to.first if to.size == 1
  state = data[:state].to_sym if data[:state]
  to.include?(state) ? state : raise_invalid_state(data)
end