has_state_machine 0.3.3 → 0.4.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/README.md +36 -7
- data/lib/has_state_machine.rb +1 -0
- data/lib/has_state_machine/deprecation.rb +7 -0
- data/lib/has_state_machine/state.rb +41 -4
- data/lib/has_state_machine/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb504bbd9b6e978b3a62551273a74624cdb4d189545cb32bf45a7f060983e888
|
4
|
+
data.tar.gz: ac89964cd89cec827ac60c8fae3970d94329c0141c0078da7a409ff2f63547ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e62938a674ba7e8bea155e536724220280458a32bfa4dc3bdeed402bba4067a54b253b76f017fec7a25b361e349b92d88daf00d8071464bc72814f96e1ae152d
|
7
|
+
data.tar.gz: cfc4cf9a5b21dc548cc4207979ac1325e5134dfe6d4fd3114ca6d623ac22ca8afcdc899cfea192030986f7ab42268405ebd6edc7201fab976752d9d6447879f9
|
data/README.md
CHANGED
@@ -7,13 +7,16 @@ HasStateMachine uses ruby classes to make creating a finite state machine for yo
|
|
7
7
|
|
8
8
|
## Contents
|
9
9
|
|
10
|
-
- [
|
11
|
-
- [
|
12
|
-
- [
|
13
|
-
- [
|
14
|
-
- [
|
10
|
+
- [HasStateMachine](#hasstatemachine)
|
11
|
+
- [Contents](#contents)
|
12
|
+
- [Installation](#installation)
|
13
|
+
- [Usage](#usage)
|
14
|
+
- [Advanced Usage](#advanced-usage)
|
15
|
+
- [Contributing](#contributing)
|
16
|
+
- [License](#license)
|
15
17
|
|
16
18
|
## Installation
|
19
|
+
|
17
20
|
Add this line to your application's Gemfile:
|
18
21
|
|
19
22
|
```ruby
|
@@ -21,11 +24,13 @@ gem 'has_state_machine'
|
|
21
24
|
```
|
22
25
|
|
23
26
|
And then execute:
|
27
|
+
|
24
28
|
```bash
|
25
29
|
$ bundle
|
26
30
|
```
|
27
31
|
|
28
32
|
Or install it yourself as:
|
33
|
+
|
29
34
|
```bash
|
30
35
|
$ gem install has_state_machine
|
31
36
|
```
|
@@ -36,6 +41,7 @@ You must first use the `has_state_machine` macro to define your state machine at
|
|
36
41
|
a high level. This includes defining the possible states for your object as well
|
37
42
|
as some optional configuration should you want to change the default behavior of
|
38
43
|
the state machine.
|
44
|
+
|
39
45
|
```ruby
|
40
46
|
# By default, it is assumed that the "state" of the object is
|
41
47
|
# stored in a string column named "status".
|
@@ -53,13 +59,13 @@ from `HasStateMachine::State`.
|
|
53
59
|
module Workflow
|
54
60
|
class Post::Draft < HasStateMachine::State
|
55
61
|
# Define the possible transitions from the "draft" state
|
56
|
-
transitions_to %i[published archived]
|
62
|
+
state_options transitions_to: %i[published archived]
|
57
63
|
end
|
58
64
|
end
|
59
65
|
|
60
66
|
module Workflow
|
61
67
|
class Post::Published < HasStateMachine::State
|
62
|
-
transitions_to %i[archived]
|
68
|
+
state_options transitions_to: %i[archived]
|
63
69
|
|
64
70
|
# Custom validations can be added to the state to ensure a transition is "valid"
|
65
71
|
validate :title_exists?
|
@@ -111,6 +117,28 @@ post.status.transition_to(:archived)
|
|
111
117
|
# => true
|
112
118
|
```
|
113
119
|
|
120
|
+
### Advanced Usage
|
121
|
+
|
122
|
+
Sometimes there may be a situation where you want to manually roll back a state change in one of the provided callbacks. To do this, add the `transactional: true` option to the `state_options` declaration and use the `rollback_transition` method in your callback. This will allow you to prevent the transition from persisting if something further down the line fails.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
module Workflow
|
126
|
+
class Post::Archived < HasStateMachine::State
|
127
|
+
state_options transactional: true
|
128
|
+
|
129
|
+
after_transition do
|
130
|
+
rollback_transition unless notified_watchers?
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def notified_watchers?
|
136
|
+
#...
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
114
142
|
## Contributing
|
115
143
|
|
116
144
|
Anyone is encouraged to help improve this project. Here are a few ways you can help:
|
@@ -130,4 +158,5 @@ bundle exec rake test
|
|
130
158
|
```
|
131
159
|
|
132
160
|
## License
|
161
|
+
|
133
162
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/has_state_machine.rb
CHANGED
@@ -16,8 +16,9 @@ module HasStateMachine
|
|
16
16
|
define_model_callbacks :transition, only: %i[before after]
|
17
17
|
|
18
18
|
##
|
19
|
-
# Retrieves the next available transitions for a given state.
|
20
|
-
|
19
|
+
# possible_transitions - Retrieves the next available transitions for a given state.
|
20
|
+
# transactional? - Determines whether or not the transition should happen with a transactional block.
|
21
|
+
delegate :possible_transitions, :transactional?, :state, to: "self.class"
|
21
22
|
|
22
23
|
##
|
23
24
|
# Add errors to the ActiveRecord object rather than the HasStateMachine::State
|
@@ -51,7 +52,13 @@ module HasStateMachine
|
|
51
52
|
with_transition_options(options) do
|
52
53
|
return false unless valid_transition?(desired_state.to_s)
|
53
54
|
|
54
|
-
|
55
|
+
desired_state = state_instance(desired_state.to_s)
|
56
|
+
|
57
|
+
transitioned = if desired_state.transactional?
|
58
|
+
desired_state.perform_transactional_transition!
|
59
|
+
else
|
60
|
+
desired_state.perform_transition!
|
61
|
+
end
|
55
62
|
end
|
56
63
|
|
57
64
|
transitioned
|
@@ -66,8 +73,24 @@ module HasStateMachine
|
|
66
73
|
end
|
67
74
|
end
|
68
75
|
|
76
|
+
##
|
77
|
+
# Makes the actual transition from one state to the next and
|
78
|
+
# runs the before and after transition callbacks in a transaction
|
79
|
+
# to allow for roll backs.
|
80
|
+
def perform_transactional_transition!
|
81
|
+
ActiveRecord::Base.transaction(requires_new: true, joinable: false) do
|
82
|
+
run_callbacks :transition do
|
83
|
+
rollback_transition unless object.update("#{object.state_attribute}": state)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
69
88
|
private
|
70
89
|
|
90
|
+
def rollback_transition
|
91
|
+
raise ActiveRecord::Rollback
|
92
|
+
end
|
93
|
+
|
71
94
|
##
|
72
95
|
# Determines if the given desired state exists in the predetermined
|
73
96
|
# list of allowed transitions.
|
@@ -111,11 +134,25 @@ module HasStateMachine
|
|
111
134
|
to_s.demodulize.underscore
|
112
135
|
end
|
113
136
|
|
137
|
+
def transactional?
|
138
|
+
@transactional || false
|
139
|
+
end
|
140
|
+
|
114
141
|
##
|
115
142
|
# Setter for the HasStateMachine::State classes to define the possible
|
116
143
|
# states the current state can transition to.
|
117
144
|
def transitions_to(states)
|
118
|
-
|
145
|
+
state_options(transitions_to: states)
|
146
|
+
HasStateMachine::Deprecation.deprecation_warning(:transitions_to, "use state_options instead")
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Set the options for the HasStateMachine::State classes to define the possible
|
151
|
+
# states the current state can transition to and whether or not transitioning
|
152
|
+
# to the state should be performed within a transaction.
|
153
|
+
def state_options(transitions_to: [], transactional: false)
|
154
|
+
@possible_transitions = transitions_to.map(&:to_s)
|
155
|
+
@transactional = transactional
|
119
156
|
end
|
120
157
|
end
|
121
158
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_state_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Hargett
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/has_state_machine.rb
|
111
111
|
- lib/has_state_machine/core_ext/string.rb
|
112
112
|
- lib/has_state_machine/definition.rb
|
113
|
+
- lib/has_state_machine/deprecation.rb
|
113
114
|
- lib/has_state_machine/railtie.rb
|
114
115
|
- lib/has_state_machine/state.rb
|
115
116
|
- lib/has_state_machine/state_helpers.rb
|