transitions 0.0.11 → 0.0.12
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.
- data/.gitignore +1 -1
- data/.rvmrc +1 -0
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/README.rdoc +15 -6
- data/lib/transitions.rb +2 -3
- data/lib/transitions/machine.rb +7 -4
- data/lib/transitions/version.rb +1 -1
- data/test/test_scopes.rb +47 -7
- data/test/test_state_transition_callbacks.rb +8 -0
- data/transitions.gemspec +1 -1
- metadata +17 -15
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.2-p290@transitions
|
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm: 1.9.2
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
+
== Travis Build Status {<img src="https://secure.travis-ci.org/troessner/transitions.png"/>}[http://travis-ci.org/troessner/transitions]
|
2
|
+
|
1
3
|
= What is transitions?
|
2
4
|
|
3
5
|
transitions is a ruby state machine implementation based on Rick Olson’s
|
4
6
|
ActiveModel::StateMachine. It was extracted from ActiveModel and turned
|
5
7
|
into a gem when it got the axe in commit {db49c706b}[http://github.com/rails/rails/commit/db49c706b62e7ea2ab93f05399dbfddf5087ee0c].
|
6
8
|
|
7
|
-
I really encourage you to try {state_machine}[https://github.com/pluginaweek/state_machine] before using this gem. Currently I have no time to maintain the gem, if you want to add some new features - contact with me.
|
8
|
-
|
9
9
|
== Quick Example
|
10
10
|
|
11
11
|
require 'transitions'
|
@@ -32,13 +32,13 @@ I really encourage you to try {state_machine}[https://github.com/pluginaweek/sta
|
|
32
32
|
|
33
33
|
== Automatic scope generation
|
34
34
|
|
35
|
-
`transitions` will automatically generate scopes for you if you are using
|
35
|
+
`transitions` will automatically generate scopes for you if you are using ActiveRecord and tell it to do so via the `auto_scopes` option:
|
36
36
|
|
37
37
|
Given a model like this:
|
38
38
|
|
39
39
|
class Order < ActiveRecord::Base
|
40
40
|
include ActiveRecord::Transitions
|
41
|
-
state_machine do
|
41
|
+
state_machine :auto_scopes => true do
|
42
42
|
state :pick_line_items
|
43
43
|
state :picking_line_items
|
44
44
|
end
|
@@ -53,7 +53,7 @@ you can use this feature a la:
|
|
53
53
|
>> Order.pick_line_items
|
54
54
|
=> [#<Order id: 3, state: "pick_line_items", description: nil, created_at: "2011-08-23 15:48:46", updated_at: "2011-08-23 15:48:46">]
|
55
55
|
|
56
|
-
== Using on_transition
|
56
|
+
== Using `on_transition`
|
57
57
|
|
58
58
|
Each event definition takes an optional "on_transition" argument, which allows you to execute methods on transition.
|
59
59
|
You can pass in a Symbol, a String, a Proc or an Array containing method names as Symbol or String like this:
|
@@ -62,6 +62,15 @@ You can pass in a Symbol, a String, a Proc or an Array containing method names a
|
|
62
62
|
transitions :to => :discontinued, :from => [:available, :out_of_stock], :on_transition => [:do_discontinue, :notify_clerk]
|
63
63
|
end
|
64
64
|
|
65
|
+
== Using `success`
|
66
|
+
|
67
|
+
In case you need to trigger a method call after a successful transition you can use `success`:
|
68
|
+
|
69
|
+
event :discontinue, :success => :notfiy_admin do
|
70
|
+
transitions :to => :discontinued, :from => [:available, :out_of_stock]
|
71
|
+
end
|
72
|
+
|
73
|
+
|
65
74
|
== Timestamps
|
66
75
|
|
67
76
|
If you'd like to note the time of a state change, Transitions comes with timestamps free!
|
@@ -121,7 +130,7 @@ bang(!)-version will call <tt>write_state</tt>.
|
|
121
130
|
|
122
131
|
== Documentation, Guides & Examples
|
123
132
|
|
124
|
-
- {Online API Documentation}[http://rdoc.info/github/
|
133
|
+
- {Online API Documentation}[http://rdoc.info/github/troessner/transitions/master/Transitions]
|
125
134
|
- Krzysiek Heród (aka {Netizer}[http://github.com/netizer]) wrote a nice
|
126
135
|
{blog post}[http://dev.netizer.pl/transitions-state-machine-for-rails-3.html]
|
127
136
|
about using Transitions in ActiveRecord.
|
data/lib/transitions.rb
CHANGED
@@ -27,9 +27,8 @@ require "transitions/state_transition"
|
|
27
27
|
require "transitions/version"
|
28
28
|
|
29
29
|
module Transitions
|
30
|
-
class InvalidTransition
|
31
|
-
|
32
|
-
end
|
30
|
+
class InvalidTransition < StandardError; end
|
31
|
+
class InvalidMethodOverride < StandardError; end
|
33
32
|
|
34
33
|
module ClassMethods
|
35
34
|
def inherited(klass)
|
data/lib/transitions/machine.rb
CHANGED
@@ -24,7 +24,7 @@ module Transitions
|
|
24
24
|
class Machine
|
25
25
|
attr_writer :initial_state
|
26
26
|
attr_accessor :states, :events, :state_index
|
27
|
-
attr_reader :klass, :name
|
27
|
+
attr_reader :klass, :name, :auto_scopes
|
28
28
|
|
29
29
|
def initialize(klass, name, options = {}, &block)
|
30
30
|
@klass, @name, @states, @state_index, @events = klass, name, [], {}, {}
|
@@ -37,8 +37,9 @@ module Transitions
|
|
37
37
|
|
38
38
|
def update(options = {}, &block)
|
39
39
|
@initial_state = options[:initial] if options.key?(:initial)
|
40
|
+
@auto_scopes = options[:auto_scopes]
|
40
41
|
instance_eval(&block) if block
|
41
|
-
include_scopes if defined?(ActiveRecord::Base) && @klass < ActiveRecord::Base
|
42
|
+
include_scopes if @auto_scopes && defined?(ActiveRecord::Base) && @klass < ActiveRecord::Base
|
42
43
|
self
|
43
44
|
end
|
44
45
|
|
@@ -48,7 +49,7 @@ module Transitions
|
|
48
49
|
state_index[new_state].call_action(:enter, record)
|
49
50
|
|
50
51
|
if record.respond_to?(event_fired_callback)
|
51
|
-
record.send(event_fired_callback, record.current_state, new_state)
|
52
|
+
record.send(event_fired_callback, record.current_state, new_state, event)
|
52
53
|
end
|
53
54
|
|
54
55
|
record.current_state(@name, new_state, persist)
|
@@ -96,7 +97,9 @@ module Transitions
|
|
96
97
|
|
97
98
|
def include_scopes
|
98
99
|
@states.each do |state|
|
99
|
-
|
100
|
+
state_name = state.name.to_s
|
101
|
+
raise InvalidMethodOverride if @klass.respond_to?(state_name)
|
102
|
+
@klass.scope state_name, @klass.where(:state => state_name)
|
100
103
|
end
|
101
104
|
end
|
102
105
|
end
|
data/lib/transitions/version.rb
CHANGED
data/test/test_scopes.rb
CHANGED
@@ -12,10 +12,30 @@ class CreateTrafficLights < ActiveRecord::Migration
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
class CreateLightBulbs < ActiveRecord::Migration
|
16
|
+
def self.up
|
17
|
+
create_table(:light_bulbs) do |t|
|
18
|
+
t.string :state
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class CreateLights < ActiveRecord::Migration
|
24
|
+
def self.up
|
25
|
+
create_table(:lights) do |t|
|
26
|
+
t.string :state
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
CreateTrafficLights.migrate(:up)
|
32
|
+
CreateLightBulbs.migrate(:up)
|
33
|
+
CreateLights.migrate(:up)
|
34
|
+
|
15
35
|
class TrafficLight < ActiveRecord::Base
|
16
36
|
include ActiveRecord::Transitions
|
17
37
|
|
18
|
-
state_machine do
|
38
|
+
state_machine :auto_scopes => true do
|
19
39
|
state :off
|
20
40
|
|
21
41
|
state :red
|
@@ -40,16 +60,18 @@ class TrafficLight < ActiveRecord::Base
|
|
40
60
|
end
|
41
61
|
end
|
42
62
|
|
43
|
-
class
|
44
|
-
|
45
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
46
|
-
ActiveRecord::Migration.verbose = false
|
47
|
-
CreateTrafficLights.migrate(:up)
|
63
|
+
class LightBulb < ActiveRecord::Base
|
64
|
+
include ActiveRecord::Transitions
|
48
65
|
|
49
|
-
|
66
|
+
state_machine do
|
67
|
+
state :off
|
68
|
+
state :on
|
50
69
|
end
|
70
|
+
end
|
51
71
|
|
72
|
+
class TestScopes < Test::Unit::TestCase
|
52
73
|
test "scope returns correct object" do
|
74
|
+
@light = TrafficLight.create!
|
53
75
|
assert TrafficLight.respond_to? :off
|
54
76
|
assert_equal TrafficLight.off.first, @light
|
55
77
|
assert TrafficLight.red.empty?
|
@@ -61,4 +83,22 @@ class TestScopes < Test::Unit::TestCase
|
|
61
83
|
assert TrafficLight.respond_to? :green
|
62
84
|
assert TrafficLight.respond_to? :yellow
|
63
85
|
end
|
86
|
+
|
87
|
+
test 'scopes are only generated if we explicitly say so' do
|
88
|
+
assert !LightBulb.respond_to?(:off)
|
89
|
+
assert !LightBulb.respond_to?(:on)
|
90
|
+
end
|
91
|
+
|
92
|
+
test 'scope generation raises an exception if we try to overwrite an existing method' do
|
93
|
+
assert_raise(Transitions::InvalidMethodOverride) {
|
94
|
+
class Light < ActiveRecord::Base
|
95
|
+
include ActiveRecord::Transitions
|
96
|
+
|
97
|
+
state_machine :auto_scopes => true do
|
98
|
+
state :new
|
99
|
+
state :broken
|
100
|
+
end
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
64
104
|
end
|
@@ -17,6 +17,9 @@ class Car
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def event_fired(current_state, new_state, event)
|
21
|
+
end
|
22
|
+
|
20
23
|
%w!start_engine loosen_handbrake push_gas_pedal!.each do |m|
|
21
24
|
define_method(m){}
|
22
25
|
end
|
@@ -40,4 +43,9 @@ class TestStateTransitionCallbacks < Test::Unit::TestCase
|
|
40
43
|
@car.expects(:push_gas_pedal).in_sequence(on_transition_sequence)
|
41
44
|
@car.start_driving!
|
42
45
|
end
|
46
|
+
|
47
|
+
test "should pass event when calling event_fired_callback" do
|
48
|
+
@car.expects(:event_fired).with(:parked, :driving, :start_driving)
|
49
|
+
@car.start_driving!
|
50
|
+
end
|
43
51
|
end
|
data/transitions.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Jakub Kuźma", "Timo Rößner"]
|
9
9
|
s.email = "timo.roessner@googlemail.com"
|
10
|
-
s.homepage = "http://github.com/
|
10
|
+
s.homepage = "http://github.com/troessner/transitions"
|
11
11
|
s.summary = "State machine extracted from ActiveModel"
|
12
12
|
s.description = "Lightweight state machine extracted from ActiveModel"
|
13
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transitions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-11-17 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
17
|
-
requirement: &
|
17
|
+
requirement: &74700350 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '1'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *74700350
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: test-unit
|
28
|
-
requirement: &
|
28
|
+
requirement: &74700040 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '2'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *74700040
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: mocha
|
39
|
-
requirement: &
|
39
|
+
requirement: &74699680 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *74699680
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: sqlite3-ruby
|
50
|
-
requirement: &
|
50
|
+
requirement: &74699290 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *74699290
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: activerecord
|
61
|
-
requirement: &
|
61
|
+
requirement: &74698870 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
version: '3'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *74698870
|
70
70
|
description: Lightweight state machine extracted from ActiveModel
|
71
71
|
email: timo.roessner@googlemail.com
|
72
72
|
executables: []
|
@@ -74,6 +74,8 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- .gitignore
|
77
|
+
- .rvmrc
|
78
|
+
- .travis.yml
|
77
79
|
- Gemfile
|
78
80
|
- Gemfile.lock
|
79
81
|
- LICENSE
|
@@ -100,7 +102,7 @@ files:
|
|
100
102
|
- test/test_state_transition_callbacks.rb
|
101
103
|
- test/test_state_transition_guard_check.rb
|
102
104
|
- transitions.gemspec
|
103
|
-
homepage: http://github.com/
|
105
|
+
homepage: http://github.com/troessner/transitions
|
104
106
|
licenses: []
|
105
107
|
post_install_message:
|
106
108
|
rdoc_options: []
|
@@ -114,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
116
|
version: '0'
|
115
117
|
segments:
|
116
118
|
- 0
|
117
|
-
hash:
|
119
|
+
hash: -171038385
|
118
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
121
|
none: false
|
120
122
|
requirements:
|
@@ -123,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
125
|
version: 1.3.6
|
124
126
|
requirements: []
|
125
127
|
rubyforge_project: transitions
|
126
|
-
rubygems_version: 1.8.
|
128
|
+
rubygems_version: 1.8.10
|
127
129
|
signing_key:
|
128
130
|
specification_version: 3
|
129
131
|
summary: State machine extracted from ActiveModel
|