state_gate 1.2.3 → 1.3.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 +4 -4
- data/lib/state_gate/builder/conflict_detection_methods.rb +59 -18
- data/lib/state_gate/builder/dynamic_module_creation_methods.rb +36 -22
- data/lib/state_gate/builder/scope_methods.rb +30 -20
- data/lib/state_gate/builder/state_methods.rb +108 -72
- data/lib/state_gate/builder/transition_methods.rb +54 -34
- data/lib/state_gate/builder/transition_validation_methods.rb +76 -66
- data/lib/state_gate/builder.rb +53 -43
- data/lib/state_gate/engine/configurator.rb +77 -63
- data/lib/state_gate/engine/errator.rb +42 -9
- data/lib/state_gate/engine/fixer.rb +21 -12
- data/lib/state_gate/engine/scoper.rb +12 -4
- data/lib/state_gate/engine/sequencer.rb +18 -5
- data/lib/state_gate/engine/stator.rb +98 -53
- data/lib/state_gate/engine/transitioner.rb +28 -14
- data/lib/state_gate/engine.rb +19 -6
- data/lib/state_gate/type.rb +22 -2
- data/lib/state_gate.rb +88 -61
- metadata +3 -3
data/lib/state_gate.rb
CHANGED
@@ -14,9 +14,9 @@ I18n.load_path << File.expand_path('state_gate/locale/state_gate_en.yml', __dir_
|
|
14
14
|
# Builds and attaches a _StateGate::Engine_ to the desired ActiveRecord String
|
15
15
|
# attribute.
|
16
16
|
#
|
17
|
-
#
|
18
|
-
# the
|
19
|
-
# for the attribute, and that
|
17
|
+
# _States_ and _transitions_ are provided within a configuration block, enabling
|
18
|
+
# the _state-gate_ to ensure that only defined _states_ are accepted as values
|
19
|
+
# for the attribute, and that _states_ may only transition to other allowed _states_.
|
20
20
|
#
|
21
21
|
# Class User
|
22
22
|
# include StateGate
|
@@ -27,12 +27,12 @@ I18n.load_path << File.expand_path('state_gate/locale/state_gate_en.yml', __dir_
|
|
27
27
|
# end
|
28
28
|
#
|
29
29
|
#
|
30
|
-
# == Attribute Name
|
30
|
+
# == The Attribute Name
|
31
31
|
#
|
32
32
|
# The +attribute_name+ *must* be:
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
33
|
+
# - a Symbol
|
34
|
+
# - the name of a database String column attribute
|
35
|
+
# - not an aliased attribute name
|
36
36
|
#
|
37
37
|
#
|
38
38
|
# == Configuration Options
|
@@ -42,75 +42,79 @@ I18n.load_path << File.expand_path('state_gate/locale/state_gate_en.yml', __dir_
|
|
42
42
|
#
|
43
43
|
# Options include:
|
44
44
|
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
45
|
+
# [state]
|
46
|
+
# Required name for the new state, supplied as a Symbol. The `state-gate` requires
|
47
|
+
# a minimum of two states to be defined.
|
48
48
|
# state :state_name
|
49
49
|
#
|
50
50
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
51
|
+
# **_:transitions_to_**
|
52
|
+
# An optional list of the other state that this state is allowed to change to.
|
53
|
+
# state :state_1, transtions_to: [:state_2, :state_3, :state_4]
|
54
|
+
# state :state_2, transtions_to: :state_4
|
55
|
+
# state :state_3, transtions_to: :any
|
56
|
+
# state :state_4
|
57
57
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
58
|
+
# **_:human_**
|
59
|
+
# An optional String name to used when displaying gthe state in a view. If no
|
60
|
+
# name is specified, it will default to +:state.titleized+.
|
61
|
+
# state :state_1, transtions_to: [:state_2, :state_3], human: "My State"
|
62
62
|
#
|
63
63
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
64
|
+
# [default]
|
65
|
+
# Optional setting to specify the default state for a new object. The state name
|
66
|
+
# is given as a Symbol.
|
67
|
+
# default :state_name
|
68
68
|
#
|
69
69
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
70
|
+
# [prefix]
|
71
|
+
# Optional setting to add a given Symbol before each state name when using Class Scopes.
|
72
|
+
# This helps to differential between multiple attributes that have similar state names.
|
73
|
+
# prefix :before #=> Class.before_active
|
74
74
|
#
|
75
75
|
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
76
|
+
# [suffix]
|
77
|
+
# Optional setting to add a given Symbol after each state name when using Class Scopes.
|
78
|
+
# This helps to differential between multiple attributes that have similar state names.
|
79
|
+
# suffix :after #=> Class.active_after
|
80
80
|
#
|
81
81
|
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
82
|
+
# [make_sequential]
|
83
|
+
# Optional setting to automatically add transitions from each state to both the
|
84
|
+
# preceeding and following states.
|
85
|
+
# make_sequential
|
86
86
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
87
|
+
# **_:one_way_**
|
88
|
+
# Option to restrict the generated transitions to one directtion only: from each
|
89
|
+
# state to the follow state.
|
90
|
+
# make_sequential :one_way
|
91
91
|
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
92
|
+
# **_:loop_**
|
93
|
+
# Option to add transitions from the last state to the first and, unless +:one_way+
|
94
|
+
# is specified, also from the first state to the last.
|
95
|
+
# make_sequential :one_way, :loop
|
96
96
|
#
|
97
97
|
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
98
|
+
# [no_scopes]
|
99
|
+
# Optional setting to disable the generation of Class Scope helpers methods.
|
100
|
+
# no_scopes
|
101
101
|
#
|
102
102
|
module StateGate
|
103
103
|
|
104
104
|
##
|
105
|
-
# Configuration Error for reporting
|
106
|
-
# building a new
|
107
|
-
|
105
|
+
# Configuration Error for reporting an invalid configuration when
|
106
|
+
# building a new _state-gate_
|
107
|
+
#
|
108
|
+
class ConfigurationError < StandardError
|
108
109
|
end
|
109
110
|
|
111
|
+
|
112
|
+
|
110
113
|
##
|
111
|
-
# Conflict Error for reporting
|
112
|
-
#
|
113
|
-
|
114
|
+
# Conflict Error for reporting a generated method name
|
115
|
+
# conflicting with an existing method name
|
116
|
+
#
|
117
|
+
class ConflictError < StandardError
|
114
118
|
end
|
115
119
|
|
116
120
|
|
@@ -120,10 +124,18 @@ module StateGate
|
|
120
124
|
|
121
125
|
##
|
122
126
|
# Returns the Symbol version of the provided value as long as it responds to
|
123
|
-
#
|
127
|
+
# _#to_s_ and has no included whitespace in the resulting String.
|
128
|
+
#
|
129
|
+
# @param [String, #to_s] val
|
130
|
+
# the string to convert in to a Symbol
|
124
131
|
#
|
125
|
-
#
|
132
|
+
# @return [Symbol]
|
133
|
+
# the converted string
|
126
134
|
#
|
135
|
+
# @return [nil]
|
136
|
+
# if the string cannot be converted
|
137
|
+
#
|
138
|
+
# @example
|
127
139
|
# StateGate.symbolize('Test') #=> :test
|
128
140
|
#
|
129
141
|
# StateGate.symbolize(:Test) #=> :test
|
@@ -155,32 +167,47 @@ module StateGate
|
|
155
167
|
|
156
168
|
|
157
169
|
|
170
|
+
##
|
158
171
|
# When StateGate is included within a Class, check ActiveRecord is
|
159
|
-
# an ancestor and add the 'state_gate' method to the
|
172
|
+
# an ancestor and add the 'state_gate' method to the including Class
|
173
|
+
#
|
174
|
+
# @param [Class]
|
175
|
+
# the Class that is including this module
|
160
176
|
#
|
161
|
-
def included(base)
|
177
|
+
def included(base)
|
162
178
|
ar_included = base.ancestors.include?(::ActiveRecord::Base)
|
163
179
|
fail I18n.t('state_gate.included_err', base: base.name) unless ar_included
|
164
180
|
|
165
|
-
|
181
|
+
_generate_state_gate_method_for(base)
|
166
182
|
end
|
167
183
|
private_class_method :included
|
168
184
|
|
169
185
|
|
170
186
|
|
187
|
+
##
|
171
188
|
# Raise an exception when StateGate is 'extend' by another Class, to let
|
172
189
|
# the user know that it should be 'included'.
|
173
190
|
#
|
174
|
-
|
191
|
+
# @param [Class]
|
192
|
+
# the Class that is extending this module
|
193
|
+
#
|
194
|
+
# @raise [RuntimeErrror]
|
195
|
+
# this module should _never_ be added through extension
|
196
|
+
#
|
197
|
+
def extended(base)
|
175
198
|
fail I18n.t('state_gate.extended_err', base: base.name)
|
176
199
|
end
|
177
200
|
|
178
201
|
|
179
202
|
|
203
|
+
##
|
180
204
|
# Calls an instance of StateGate::Builder to generate the
|
181
|
-
#
|
205
|
+
# _state_gate_ for the Klass attribute.
|
206
|
+
#
|
207
|
+
# @param [Class]
|
208
|
+
# the Class the _state-gate_ is being attached to
|
182
209
|
#
|
183
|
-
def
|
210
|
+
def _generate_state_gate_method_for(klass)
|
184
211
|
klass.define_singleton_method(:state_gate) do |attr_name = nil, &block|
|
185
212
|
# Note: the builder does all it's work on initialize, so nothing more
|
186
213
|
# to do here.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: state_gate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CodeMeister
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
requirements: []
|
79
|
-
rubygems_version: 3.
|
79
|
+
rubygems_version: 3.5.17
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: State management for ActiveRecord.
|