statesman 0.4.0 → 0.5.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/.rubocop.yml +3 -0
- data/CHANGELOG.md +8 -0
- data/README.md +38 -0
- data/lib/statesman.rb +4 -0
- data/lib/statesman/adapters/active_record_model.rb +46 -0
- data/lib/statesman/machine.rb +1 -0
- data/lib/statesman/version.rb +1 -1
- data/spec/statesman/adapters/active_record_model_spec.rb +57 -0
- data/spec/statesman/machine_spec.rb +10 -0
- data/spec/statesman/transition_spec.rb +1 -0
- data/spec/support/active_record.rb +2 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7705af0277715fcc157ab5d750e870c03ff589fb
|
4
|
+
data.tar.gz: e05d77943df6c572a9ea9d45b59f94f2c758cb6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed5f485322fd9c0a906d0a010812e72a704db3669bc915c2aba8b942f6a9f98ff8145907adc5ab023440b997b0f9fdf9758aa7e0e67568afc391df505b7c7476
|
7
|
+
data.tar.gz: bd202c6eafdbb989545e5b0f361a9713ef95fe78bb3b7454856a20e266fdd1f5a1b5242d1cc593123bf310aac202be47ccbef4f624c9d12a5dc59129dc6f1649
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## v0.5.0, 27 March 2014
|
2
|
+
*Additions*
|
3
|
+
- Scope methods. Adds a module which can be mixed in to an ActiveRecord model to provide `.in_state` and `.not_in_state` query scopes.
|
4
|
+
- Adds `Machine#after_initialize` hook (patch by [@att14](https://github.com/att14))
|
5
|
+
|
6
|
+
*Fixes*
|
7
|
+
- Added MongoidTransition to the autoload statements, fixing [#29](https://github.com/gocardless/statesman/issues/29) (patch by [@tomclose](https://github.com/tomclose))
|
8
|
+
|
1
9
|
## v0.4.0, 27 February 2014
|
2
10
|
*Additions*
|
3
11
|
- Adds after_commit flag to after_transition for callbacks to be executed after the transaction has been
|
data/README.md
CHANGED
@@ -53,11 +53,19 @@ class OrderStateMachine
|
|
53
53
|
end
|
54
54
|
|
55
55
|
class Order < ActiveRecord::Base
|
56
|
+
include Statesman::Adapters::ActiveRecordModel
|
57
|
+
|
56
58
|
has_many :order_transitions
|
57
59
|
|
58
60
|
def state_machine
|
59
61
|
OrderStateMachine.new(self, transition_class: OrderTransition)
|
60
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def transition_class
|
67
|
+
OrderTransition
|
68
|
+
end
|
61
69
|
end
|
62
70
|
|
63
71
|
class OrderTransition < ActiveRecord::Base
|
@@ -78,6 +86,12 @@ Order.first.state_machine.can_transition_to?(:cancelled)
|
|
78
86
|
Order.first.state_machine.transition_to(:cancelled, optional: :metadata)
|
79
87
|
# => true/false
|
80
88
|
|
89
|
+
Order.in_state(:cancelled)
|
90
|
+
# => [#<Order id: "123">]
|
91
|
+
|
92
|
+
Order.not_in_state(:checking_out)
|
93
|
+
# => [#<Order id: "123">]
|
94
|
+
|
81
95
|
Order.first.state_machine.transition_to!(:cancelled)
|
82
96
|
# => true/exception
|
83
97
|
```
|
@@ -219,6 +233,30 @@ Transition to the passed state, returning `true` on success. Raises
|
|
219
233
|
Transition to the passed state, returning `true` on success. Swallows all
|
220
234
|
exceptions and returns false on failure.
|
221
235
|
|
236
|
+
## Model scopes
|
237
|
+
|
238
|
+
A mixin is provided for the ActiveRecord adapter which adds scopes to easily
|
239
|
+
find all models currently in (or not in) a given state. Include it into your
|
240
|
+
model and define a `transition_class` method.
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
class Order < ActiveRecord::Base
|
244
|
+
include Statesman::Adapters::ActiveRecordModel
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
def transition_class
|
249
|
+
OrderTransition
|
250
|
+
end
|
251
|
+
end
|
252
|
+
```
|
253
|
+
|
254
|
+
#### `Model.in_state(:state_1, :state_2, etc)`
|
255
|
+
Returns all models currently in any of the supplied states.
|
256
|
+
|
257
|
+
#### `Model.not_in_state(:state_1, :state_2, etc)`
|
258
|
+
Returns all models not currently in any of the supplied states.
|
259
|
+
|
222
260
|
---
|
223
261
|
|
224
262
|
GoCardless ♥ open source. If you do too, come [join us](https://gocardless.com/jobs/backend_developer).
|
data/lib/statesman.rb
CHANGED
@@ -9,7 +9,11 @@ module Statesman
|
|
9
9
|
autoload :ActiveRecord, "statesman/adapters/active_record"
|
10
10
|
autoload :ActiveRecordTransition,
|
11
11
|
"statesman/adapters/active_record_transition"
|
12
|
+
autoload :ActiveRecordModel,
|
13
|
+
"statesman/adapters/active_record_model"
|
12
14
|
autoload :Mongoid, "statesman/adapters/mongoid"
|
15
|
+
autoload :MongoidTransition,
|
16
|
+
"statesman/adapters/mongoid_transition"
|
13
17
|
end
|
14
18
|
|
15
19
|
# Example:
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Statesman
|
2
|
+
module Adapters
|
3
|
+
module ActiveRecordModel
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def in_state(*states)
|
10
|
+
joins(transition_name)
|
11
|
+
.joins(transition_join)
|
12
|
+
.where("#{transition_name}.to_state" => states)
|
13
|
+
.where("transition2.id" => nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def not_in_state(*states)
|
17
|
+
joins(transition_name)
|
18
|
+
.joins(transition_join)
|
19
|
+
.where("#{transition_name}.to_state NOT IN (?)", states)
|
20
|
+
.where("transition2.id" => nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def transition_class
|
26
|
+
raise NotImplementedError, "A transition_class method should be " +
|
27
|
+
"defined on the model"
|
28
|
+
end
|
29
|
+
|
30
|
+
def transition_name
|
31
|
+
transition_class.table_name.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def model_foreign_key
|
35
|
+
reflections[transition_name].foreign_key
|
36
|
+
end
|
37
|
+
|
38
|
+
def transition_join
|
39
|
+
"LEFT OUTER JOIN #{transition_name} transition2
|
40
|
+
ON transition2.#{model_foreign_key} = #{table_name}.id
|
41
|
+
AND transition2.sort_key > #{transition_name}.sort_key"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/statesman/machine.rb
CHANGED
data/lib/statesman/version.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Statesman::Adapters::ActiveRecordModel do
|
4
|
+
before do
|
5
|
+
prepare_model_table
|
6
|
+
prepare_transitions_table
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
MyActiveRecordModel.send(:include, Statesman::Adapters::ActiveRecordModel)
|
11
|
+
MyActiveRecordModel.class_eval do
|
12
|
+
def self.transition_class
|
13
|
+
MyActiveRecordModelTransition
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let!(:model) do
|
19
|
+
model = MyActiveRecordModel.create
|
20
|
+
model.my_active_record_model_transitions.create(to_state: :state_a)
|
21
|
+
model
|
22
|
+
end
|
23
|
+
|
24
|
+
let!(:other_model) do
|
25
|
+
model = MyActiveRecordModel.create
|
26
|
+
model.my_active_record_model_transitions.create(to_state: :state_b)
|
27
|
+
model
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".in_state" do
|
31
|
+
context "given a single state" do
|
32
|
+
subject { MyActiveRecordModel.in_state(:state_a) }
|
33
|
+
|
34
|
+
it { should include model }
|
35
|
+
end
|
36
|
+
|
37
|
+
context "given multiple states" do
|
38
|
+
subject { MyActiveRecordModel.in_state(:state_a, :state_b) }
|
39
|
+
|
40
|
+
it { should include model }
|
41
|
+
it { should include other_model }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".not_in_state" do
|
46
|
+
context "given a single state" do
|
47
|
+
subject { MyActiveRecordModel.not_in_state(:state_b) }
|
48
|
+
it { should include model }
|
49
|
+
it { should_not include other_model }
|
50
|
+
end
|
51
|
+
|
52
|
+
context "given multiple states" do
|
53
|
+
subject { MyActiveRecordModel.not_in_state(:state_a, :state_b) }
|
54
|
+
it { should == [] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -206,6 +206,16 @@ describe Statesman::Machine do
|
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
209
|
+
describe "#after_initialize" do
|
210
|
+
it "is called after initialize" do
|
211
|
+
machine.class_eval do
|
212
|
+
def after_initialize; end
|
213
|
+
end
|
214
|
+
expect_any_instance_of(machine).to receive :after_initialize
|
215
|
+
machine.new(my_model)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
209
219
|
describe "#current_state" do
|
210
220
|
before do
|
211
221
|
machine.class_eval do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "support/active_record"
|
2
|
+
require "json"
|
2
3
|
|
3
4
|
DB = Pathname.new("test.sqlite3")
|
4
5
|
|
@@ -8,6 +9,7 @@ end
|
|
8
9
|
|
9
10
|
class MyActiveRecordModelTransition < ActiveRecord::Base
|
10
11
|
belongs_to :my_active_record_model
|
12
|
+
serialize :metadata, JSON
|
11
13
|
end
|
12
14
|
|
13
15
|
class CreateMyActiveRecordModelMigration < ActiveRecord::Migration
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: statesman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Marr
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -163,6 +163,7 @@ files:
|
|
163
163
|
- lib/generators/statesman/templates/update_migration.rb.erb
|
164
164
|
- lib/statesman.rb
|
165
165
|
- lib/statesman/adapters/active_record.rb
|
166
|
+
- lib/statesman/adapters/active_record_model.rb
|
166
167
|
- lib/statesman/adapters/active_record_transition.rb
|
167
168
|
- lib/statesman/adapters/memory.rb
|
168
169
|
- lib/statesman/adapters/memory_transition.rb
|
@@ -175,6 +176,7 @@ files:
|
|
175
176
|
- lib/statesman/machine.rb
|
176
177
|
- lib/statesman/version.rb
|
177
178
|
- spec/spec_helper.rb
|
179
|
+
- spec/statesman/adapters/active_record_model_spec.rb
|
178
180
|
- spec/statesman/adapters/active_record_spec.rb
|
179
181
|
- spec/statesman/adapters/active_record_transition_spec.rb
|
180
182
|
- spec/statesman/adapters/memory_spec.rb
|
@@ -214,6 +216,7 @@ specification_version: 4
|
|
214
216
|
summary: A statesmanlike state machine library
|
215
217
|
test_files:
|
216
218
|
- spec/spec_helper.rb
|
219
|
+
- spec/statesman/adapters/active_record_model_spec.rb
|
217
220
|
- spec/statesman/adapters/active_record_spec.rb
|
218
221
|
- spec/statesman/adapters/active_record_transition_spec.rb
|
219
222
|
- spec/statesman/adapters/memory_spec.rb
|