transitions 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
|