aasm 3.0.1 → 3.0.2
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/CHANGELOG.md +4 -0
- data/LICENSE +1 -1
- data/README.md +31 -5
- data/lib/aasm/base.rb +7 -0
- data/lib/aasm/persistence/active_record_persistence.rb +6 -1
- data/lib/aasm/version.rb +1 -1
- data/spec/models/invalid_persistor.rb +16 -0
- data/spec/models/validator.rb +16 -0
- data/spec/schema.rb +10 -0
- data/spec/unit/aasm_spec.rb +1 -72
- data/spec/unit/active_record_persistence_spec.rb +49 -0
- data/spec/unit/localizer_spec.rb +5 -2
- metadata +8 -4
data/CHANGELOG.md
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
This package contains AASM, a library for adding finite state machines to Ruby classes.
|
4
4
|
|
5
|
-
AASM started as the acts_as_state_machine plugin but has evolved into a more generic library
|
5
|
+
AASM started as the acts_as_state_machine plugin but has evolved into a more generic library
|
6
|
+
that no longer targets only ActiveRecord models. It currently provides adapters for
|
7
|
+
[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) and
|
8
|
+
[Mongoid](http://mongoid.org/).
|
6
9
|
|
7
10
|
## Features ##
|
8
11
|
|
@@ -54,7 +57,9 @@ gem 'aasm'
|
|
54
57
|
% sudo gem install pkg/aasm-x.y.z.gem
|
55
58
|
```
|
56
59
|
|
57
|
-
##
|
60
|
+
## Examples ##
|
61
|
+
|
62
|
+
### Simple Example ###
|
58
63
|
|
59
64
|
Here's a quick example highlighting some of the features.
|
60
65
|
|
@@ -79,7 +84,7 @@ class Conversation
|
|
79
84
|
end
|
80
85
|
```
|
81
86
|
|
82
|
-
|
87
|
+
### A Slightly More Complex Example ###
|
83
88
|
|
84
89
|
This example uses a few of the more complex features available.
|
85
90
|
|
@@ -114,7 +119,7 @@ This example uses a few of the more complex features available.
|
|
114
119
|
end
|
115
120
|
```
|
116
121
|
|
117
|
-
|
122
|
+
### Callbacks around events ###
|
118
123
|
```ruby
|
119
124
|
class Relationship
|
120
125
|
include AASM
|
@@ -132,6 +137,27 @@ This example uses a few of the more complex features available.
|
|
132
137
|
end
|
133
138
|
```
|
134
139
|
|
140
|
+
### Persistence example ###
|
141
|
+
```ruby
|
142
|
+
class InvalidPersistor < ActiveRecord::Base
|
143
|
+
include AASM
|
144
|
+
aasm :column => :status, :skip_validation_on_save => true do
|
145
|
+
state :sleeping, :initial => true
|
146
|
+
state :running
|
147
|
+
event :run do
|
148
|
+
transitions :to => :running, :from => :sleeping
|
149
|
+
end
|
150
|
+
event :sleep do
|
151
|
+
transitions :to => :sleeping, :from => :running
|
152
|
+
end
|
153
|
+
end
|
154
|
+
validates_presence_of :name
|
155
|
+
end
|
156
|
+
```
|
157
|
+
This model can change AASM states which are stored into the database, even if the model itself is invalid!
|
158
|
+
|
159
|
+
|
160
|
+
|
135
161
|
## Changelog ##
|
136
162
|
|
137
163
|
Look at the [CHANGELOG](https://github.com/rubyist/aasm/blob/master/CHANGELOG.md) for details.
|
@@ -153,7 +179,7 @@ purpose.
|
|
153
179
|
|
154
180
|
## License ##
|
155
181
|
|
156
|
-
Copyright (c) 2006-
|
182
|
+
Copyright (c) 2006-2012 Scott Barron
|
157
183
|
|
158
184
|
Permission is hereby granted, free of charge, to any person obtaining
|
159
185
|
a copy of this software and associated documentation files (the
|
data/lib/aasm/base.rb
CHANGED
@@ -4,11 +4,18 @@ module AASM
|
|
4
4
|
@clazz = clazz
|
5
5
|
sm = AASM::StateMachine[@clazz]
|
6
6
|
sm.config.column = options[:column].to_sym if options[:column]
|
7
|
+
|
7
8
|
if options.key?(:whiny_transitions)
|
8
9
|
sm.config.whiny_transitions = options[:whiny_transitions]
|
9
10
|
else
|
10
11
|
sm.config.whiny_transitions = true # this is the default, so let's cry
|
11
12
|
end
|
13
|
+
|
14
|
+
if options.key?(:skip_validation_on_save)
|
15
|
+
sm.config.skip_validation_on_save = options[:skip_validation_on_save]
|
16
|
+
else
|
17
|
+
sm.config.skip_validation_on_save = false # this is the default, so don't store any new state if the model is invalid
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
def state(name, options={})
|
@@ -196,7 +196,12 @@ module AASM
|
|
196
196
|
old_value = read_attribute(self.class.aasm_column)
|
197
197
|
write_attribute(self.class.aasm_column, state.to_s)
|
198
198
|
|
199
|
-
|
199
|
+
success = if AASM::StateMachine[self.class].config.skip_validation_on_save && !self.valid?
|
200
|
+
self.class.update_all({ self.class.aasm_column => state.to_s }, self.class.primary_key => self.id) == 1
|
201
|
+
else
|
202
|
+
self.save
|
203
|
+
end
|
204
|
+
unless success
|
200
205
|
write_attribute(self.class.aasm_column, old_value)
|
201
206
|
return false
|
202
207
|
end
|
data/lib/aasm/version.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class InvalidPersistor < ActiveRecord::Base
|
4
|
+
include AASM
|
5
|
+
aasm :column => :status, :skip_validation_on_save => true do
|
6
|
+
state :sleeping, :initial => true
|
7
|
+
state :running
|
8
|
+
event :run do
|
9
|
+
transitions :to => :running, :from => :sleeping
|
10
|
+
end
|
11
|
+
event :sleep do
|
12
|
+
transitions :to => :sleeping, :from => :running
|
13
|
+
end
|
14
|
+
end
|
15
|
+
validates_presence_of :name
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class Validator < ActiveRecord::Base
|
4
|
+
include AASM
|
5
|
+
aasm :column => :status do
|
6
|
+
state :sleeping, :initial => true
|
7
|
+
state :running
|
8
|
+
event :run do
|
9
|
+
transitions :to => :running, :from => :sleeping
|
10
|
+
end
|
11
|
+
event :sleep do
|
12
|
+
transitions :to => :sleeping, :from => :running
|
13
|
+
end
|
14
|
+
end
|
15
|
+
validates_presence_of :name
|
16
|
+
end
|
data/spec/schema.rb
CHANGED
@@ -4,4 +4,14 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
4
4
|
create_table table_name, :force => true
|
5
5
|
end
|
6
6
|
|
7
|
+
create_table "validators", :force => true do |t|
|
8
|
+
t.string "name"
|
9
|
+
t.string "status"
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table "invalid_persistors", :force => true do |t|
|
13
|
+
t.string "name"
|
14
|
+
t.string "status"
|
15
|
+
end
|
16
|
+
|
7
17
|
end
|
data/spec/unit/aasm_spec.rb
CHANGED
@@ -103,75 +103,16 @@ describe AASM, '- initial states' do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
describe AASM, '
|
107
|
-
it 'should update the current state' do
|
108
|
-
foo = Foo.new
|
109
|
-
foo.close!
|
110
|
-
|
111
|
-
foo.aasm_current_state.should == :closed
|
112
|
-
end
|
113
|
-
|
106
|
+
describe AASM, 'success callbacks' do
|
114
107
|
it 'should call the success callback if one was provided' do
|
115
108
|
foo = Foo.new
|
116
|
-
|
117
109
|
foo.should_receive(:success_callback)
|
118
|
-
|
119
110
|
foo.close!
|
120
111
|
end
|
121
112
|
|
122
|
-
it 'should attempt to persist if aasm_write_state is defined' do
|
123
|
-
foo = Foo.new
|
124
|
-
|
125
|
-
def foo.aasm_write_state
|
126
|
-
end
|
127
|
-
|
128
|
-
foo.should_receive(:aasm_write_state)
|
129
|
-
|
130
|
-
foo.close!
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'should return true if aasm_write_state is defined and returns true' do
|
134
|
-
foo = Foo.new
|
135
|
-
|
136
|
-
def foo.aasm_write_state(state)
|
137
|
-
true
|
138
|
-
end
|
139
|
-
|
140
|
-
foo.close!.should be_true
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'should return false if aasm_write_state is defined and returns false' do
|
144
|
-
foo = Foo.new
|
145
|
-
|
146
|
-
def foo.aasm_write_state(state)
|
147
|
-
false
|
148
|
-
end
|
149
|
-
|
150
|
-
foo.close!.should be_false
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should not update the aasm_current_state if the write fails" do
|
154
|
-
foo = Foo.new
|
155
|
-
|
156
|
-
def foo.aasm_write_state
|
157
|
-
false
|
158
|
-
end
|
159
|
-
|
160
|
-
foo.should_receive(:aasm_write_state)
|
161
|
-
|
162
|
-
foo.close!
|
163
|
-
foo.aasm_current_state.should == :open
|
164
|
-
end
|
165
113
|
end
|
166
114
|
|
167
115
|
describe AASM, '- event firing without persistence' do
|
168
|
-
it 'should update the current state' do
|
169
|
-
foo = Foo.new
|
170
|
-
foo.close
|
171
|
-
|
172
|
-
foo.aasm_current_state.should == :closed
|
173
|
-
end
|
174
|
-
|
175
116
|
it 'should attempt to persist if aasm_write_state is defined' do
|
176
117
|
foo = Foo.new
|
177
118
|
|
@@ -184,18 +125,6 @@ describe AASM, '- event firing without persistence' do
|
|
184
125
|
end
|
185
126
|
end
|
186
127
|
|
187
|
-
describe AASM, '- persistence' do
|
188
|
-
it 'should read the state if it has not been set and aasm_read_state is defined' do
|
189
|
-
foo = Foo.new
|
190
|
-
def foo.aasm_read_state
|
191
|
-
end
|
192
|
-
|
193
|
-
foo.should_receive(:aasm_read_state)
|
194
|
-
|
195
|
-
foo.aasm_current_state
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
128
|
describe AASM, '- getting events for a state' do
|
200
129
|
it '#aasm_events_for_current_state should use current state' do
|
201
130
|
foo = Foo.new
|
@@ -246,3 +246,52 @@ describe 'Thieves' do
|
|
246
246
|
Thief.new(:skilled => false).aasm_current_state.should == :jailed
|
247
247
|
end
|
248
248
|
end
|
249
|
+
|
250
|
+
describe 'transitions with persistence' do
|
251
|
+
|
252
|
+
it 'should not store states for invalid models' do
|
253
|
+
validator = Validator.create(:name => 'name')
|
254
|
+
validator.should be_valid
|
255
|
+
validator.should be_sleeping
|
256
|
+
|
257
|
+
validator.name = nil
|
258
|
+
validator.should_not be_valid
|
259
|
+
validator.run!.should be_false
|
260
|
+
validator.should be_sleeping
|
261
|
+
|
262
|
+
validator.reload
|
263
|
+
validator.should_not be_running
|
264
|
+
validator.should be_sleeping
|
265
|
+
|
266
|
+
validator.name = 'another name'
|
267
|
+
validator.should be_valid
|
268
|
+
validator.run!.should be_true
|
269
|
+
validator.should be_running
|
270
|
+
|
271
|
+
validator.reload
|
272
|
+
validator.should be_running
|
273
|
+
validator.should_not be_sleeping
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'should store states for invalid models if configured' do
|
277
|
+
persistor = InvalidPersistor.create(:name => 'name')
|
278
|
+
persistor.should be_valid
|
279
|
+
persistor.should be_sleeping
|
280
|
+
|
281
|
+
persistor.name = nil
|
282
|
+
persistor.should_not be_valid
|
283
|
+
persistor.run!.should be_true
|
284
|
+
persistor.should be_running
|
285
|
+
|
286
|
+
persistor = InvalidPersistor.find(persistor.id)
|
287
|
+
persistor.valid?
|
288
|
+
persistor.should be_valid
|
289
|
+
persistor.should be_running
|
290
|
+
persistor.should_not be_sleeping
|
291
|
+
|
292
|
+
persistor.reload
|
293
|
+
persistor.should be_running
|
294
|
+
persistor.should_not be_sleeping
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
data/spec/unit/localizer_spec.rb
CHANGED
@@ -22,16 +22,19 @@ describe AASM::SupportingClasses::Localizer do
|
|
22
22
|
before(:all) do
|
23
23
|
I18n.load_path << 'spec/en.yml'
|
24
24
|
I18n.default_locale = :en
|
25
|
+
I18n.reload!
|
25
26
|
end
|
26
27
|
|
27
|
-
after(:all)
|
28
|
+
after(:all) do
|
29
|
+
I18n.load_path.clear
|
30
|
+
end
|
28
31
|
|
29
32
|
let (:foo_opened) { LocalizerTestModel.new }
|
30
33
|
let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
|
31
34
|
|
32
35
|
context 'aasm_human_state' do
|
33
36
|
it 'should return translated state value' do
|
34
|
-
|
37
|
+
foo_opened.aasm_human_state.should == "It's opened now!"
|
35
38
|
end
|
36
39
|
|
37
40
|
it 'should return humanized value if not localized' do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 3.0.
|
9
|
+
- 2
|
10
|
+
version: 3.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Scott Barron
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date:
|
21
|
+
date: 2012-01-16 00:00:00 +01:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -182,9 +182,11 @@ files:
|
|
182
182
|
- spec/database.yml
|
183
183
|
- spec/en.yml
|
184
184
|
- spec/models/conversation.rb
|
185
|
+
- spec/models/invalid_persistor.rb
|
185
186
|
- spec/models/not_auto_loaded/process.rb
|
186
187
|
- spec/models/process_with_new_dsl.rb
|
187
188
|
- spec/models/silencer.rb
|
189
|
+
- spec/models/validator.rb
|
188
190
|
- spec/schema.rb
|
189
191
|
- spec/spec_helper.rb
|
190
192
|
- spec/spec_helpers/models_spec_helper.rb
|
@@ -237,9 +239,11 @@ test_files:
|
|
237
239
|
- spec/database.yml
|
238
240
|
- spec/en.yml
|
239
241
|
- spec/models/conversation.rb
|
242
|
+
- spec/models/invalid_persistor.rb
|
240
243
|
- spec/models/not_auto_loaded/process.rb
|
241
244
|
- spec/models/process_with_new_dsl.rb
|
242
245
|
- spec/models/silencer.rb
|
246
|
+
- spec/models/validator.rb
|
243
247
|
- spec/schema.rb
|
244
248
|
- spec/spec_helper.rb
|
245
249
|
- spec/spec_helpers/models_spec_helper.rb
|