Module: SolidState::ClassMethods

Defined in:
lib/solidstate.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#possible_statesObject

Returns the value of attribute possible_states.



11
12
13
# File 'lib/solidstate.rb', line 11

def possible_states
  @possible_states
end

#state_transitionsObject

Returns the value of attribute state_transitions.



12
13
14
# File 'lib/solidstate.rb', line 12

def state_transitions
  @state_transitions
end

Instance Method Details

#states(*list, &block) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/solidstate.rb', line 14

def states(*list, &block)
  list = list.collect(&:to_s)

  raise "states have already been set! To get list of possible states, call #{name}.possible_states" if self.possible_states
  raise "This is not a list of names" unless list.first.respond_to?(:downcase)

  self.possible_states = list
  self.state_transitions = {}

  if respond_to?(:validates_inclusion_of)
    validates_inclusion_of STATE_ATTRIBUTE, in: list
  end

  scope :with_state, lambda { |state|
    return query if state.blank?
    where(STATE_ATTRIBUTE => state)
  } if respond_to?(:scope)

  list.each do |s|
    scope(s, lambda { where(STATE_ATTRIBUTE => s) }) if respond_to?(:scope)

    define_method "#{s}?" do
      state.to_sym == s.to_sym
    end
  end

  yield if block_given?
end

#transitions(opts) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/solidstate.rb', line 43

def transitions(opts)
  validate :ensure_valid_transition if respond_to?(:validate)

  from = opts.delete(:from) or raise ":from required"
  to   = opts.delete(:to)   or raise ":to required"
  to   = [to] unless to.is_a?(Array)

  # puts "From #{from} to #{to.join(' or ')}"
  to.each do |dest|

    self.state_transitions[from.to_sym] ||= []
    self.state_transitions[from.to_sym].push(dest.to_sym)

    define_method("#{dest}!") do
      unless set_state(dest.to_sym)
        raise InvalidTransitionError.new("Cannot transition from #{state} to #{dest}")
      end

      if !respond_to?(:valid?) or (valid? && save)
        send("once_#{dest}", from) if respond_to?("once_#{dest}")
        send("once_not_#{from}", dest) if respond_to?("once_not_#{from}")
        true
      else
        false
      end
    end
  end
end