stateful_enum 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5b8fa0430831e495e52e5fad80462db2100a9a8
4
- data.tar.gz: ace6e802d2fa0abd9b047c23215dd0e2b8a70033
3
+ metadata.gz: ffeec178154391f427428dcb96dfe904071069a8
4
+ data.tar.gz: 9928fb31c685db67d2a9d70d232b0d9736fa88ad
5
5
  SHA512:
6
- metadata.gz: c2b6c81796a16ded357ff40cac7c2cfc37eb6570516d685ef59afe897a8d34cb270ace9e5e3b514aeface34072f5c3186e26cb69b8320acdbdc6cef039431093
7
- data.tar.gz: 43019bdc355a9352af8a674f42a10b4d12f4fe64776c17089e731ea15109f0ab5b7c95ff476fbc3c493ba601e4570f00f51aa28514b3d9ff14ad1adc97de3715
6
+ metadata.gz: 9330b01347ddc68584bd6b87417e22d0577eb6f15e4a902c40af48b5a60b408977ff799df33280eed09800421004b1c3e9bffe264d00b017f38a5545f22352cb
7
+ data.tar.gz: 9bad2968b578fcf1141fb78c1b69284a6750c64596a68056ff733173aba2492f58842ff6005bffd79ee435d7140f079e44e2ee0e52b814a065ce64e187f337d3
data/README.md CHANGED
@@ -41,13 +41,26 @@ The stateful_enum gem extends AR::Enum definition to take a block with a similar
41
41
  Example:
42
42
  ```ruby
43
43
  class Bug < ApplicationRecord
44
- enum status: {unassigned: 0, assigned: 1, resolved: 2} do
44
+ enum status: {unassigned: 0, assigned: 1, resolved: 2, closed: 3} do
45
45
  event :assign do
46
46
  transition :unassigned => :assigned
47
47
  end
48
+
48
49
  event :resolve do
50
+ before do
51
+ self.resolved_at = Time.zone.now
52
+ end
53
+
49
54
  transition [:unassigned, :assigned] => :resolved
50
55
  end
56
+
57
+ event :close do
58
+ after do
59
+ Notifier.notify "Bug##{id} has been closed."
60
+ end
61
+
62
+ transition all - [:closed] => :closed
63
+ end
51
64
  end
52
65
  end
53
66
  ```
@@ -91,22 +104,27 @@ There are a few important details to note regarding this feature:
91
104
  * The `transition` method takes a Hash each key of which is state "from" transitions to the Hash value.
92
105
  * The "from" states and the "to" states should both be given in Symbols.
93
106
  * The "from" state can be multiple states, in which case the key can be given as an Array of states, as shown in the usage example.
107
+ * The "from" state can be `all` that means all defined states.
94
108
 
95
- ### Error handling
109
+ ### :if and :unless Condition
96
110
 
97
- **TODO**
111
+ The `transition` method takes an `:if` or `:unless` option as a Proc.
98
112
 
99
- ### Event hooks
113
+ Example:
114
+ ```ruby
115
+ event :assign do
116
+ transition :unassigned => :assigned, if: -> { !!assigned_to }
117
+ end
118
+ ```
100
119
 
101
- **TODO**
120
+ ### Event hooks
102
121
 
103
- ### Guards (:if and :unless options)
122
+ You can define `before` and `after` event hooks inside of an `event` block.
104
123
 
105
- **TODO**
106
124
 
107
- ### Transition from "all"
125
+ ## TODO
108
126
 
109
- **TODO**
127
+ * Better Error handling
110
128
 
111
129
 
112
130
  ## Contributing
@@ -27,11 +27,17 @@ module StatefulEnum
27
27
  end
28
28
 
29
29
  def define_transition_methods
30
- column, name, transitions = @column, @name, @transitions
30
+ column, name, transitions, before, after = @column, @name, @transitions, @before, @after
31
31
 
32
32
  @model.send(:define_method, name) do
33
- if (to = transitions[self.send(column).to_sym])
34
- self.class.instance_variable_get(:@_enum_methods_module).instance_method("#{to}!").bind(self).call
33
+ to, condition = transitions[self.send(column).to_sym]
34
+ #TODO better error
35
+ if to && (!condition || instance_exec(&condition))
36
+ #TODO transaction?
37
+ instance_eval(&before) if before
38
+ ret = self.class.instance_variable_get(:@_enum_methods_module).instance_method("#{to}!").bind(self).call
39
+ instance_eval(&after) if after
40
+ ret
35
41
  else
36
42
  false
37
43
  end
@@ -46,19 +52,38 @@ module StatefulEnum
46
52
  end
47
53
 
48
54
  @model.send(:define_method, "#{name}_transition") do
49
- transitions[self.send(column).to_sym]
55
+ transitions[self.send(column).to_sym].try! :first
50
56
  end
51
57
  end
52
58
 
53
- def transition(transitions)
59
+ def transition(transitions, options = {})
60
+ if options.blank?
61
+ options[:if] = transitions.delete :if
62
+ #TODO should err if if & unless were specified together?
63
+ if (unless_condition = transitions.delete :unless)
64
+ options[:if] = -> { !instance_exec(&unless_condition) }
65
+ end
66
+ end
54
67
  transitions.each_pair do |from, to|
55
68
  raise "Undefined state #{to}" unless @states.has_key? to
56
69
  Array(from).each do |f|
57
70
  raise "Undefined state #{f}" unless @states.has_key? f
58
- @transitions[f] = to
71
+ @transitions[f] = [to, options[:if]]
59
72
  end
60
73
  end
61
74
  end
75
+
76
+ def all
77
+ @states.keys
78
+ end
79
+
80
+ def before(&block)
81
+ @before = block
82
+ end
83
+
84
+ def after(&block)
85
+ @after = block
86
+ end
62
87
  end
63
88
  end
64
89
  end
@@ -1,3 +1,3 @@
1
1
  module StatefulEnum
2
- VERSION = "0.1.0"
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stateful_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Matsuda