aasm 3.0.24 → 3.1.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +23 -4
  4. data/CHANGELOG.md +20 -0
  5. data/Gemfile +9 -1
  6. data/LICENSE +1 -1
  7. data/README.md +65 -12
  8. data/aasm.gemspec +5 -6
  9. data/gemfiles/rails_3.2.gemfile +12 -0
  10. data/gemfiles/rails_4.0.gemfile +11 -0
  11. data/gemfiles/rails_4.1.gemfile +11 -0
  12. data/lib/aasm/aasm.rb +31 -27
  13. data/lib/aasm/base.rb +35 -20
  14. data/lib/aasm/event.rb +27 -16
  15. data/lib/aasm/instance_base.rb +3 -1
  16. data/lib/aasm/persistence/active_record_persistence.rb +27 -9
  17. data/lib/aasm/persistence/base.rb +1 -1
  18. data/lib/aasm/persistence/mongoid_persistence.rb +10 -8
  19. data/lib/aasm/state.rb +1 -0
  20. data/lib/aasm/transition.rb +13 -6
  21. data/lib/aasm/version.rb +1 -1
  22. data/lib/aasm.rb +0 -3
  23. data/spec/database.rb +33 -0
  24. data/spec/models/guardian.rb +48 -0
  25. data/spec/models/mongoid/no_scope_mongoid.rb +1 -1
  26. data/spec/models/mongoid/simple_mongoid.rb +5 -4
  27. data/spec/models/mongoid/simple_new_dsl_mongoid.rb +1 -1
  28. data/spec/models/not_auto_loaded/process.rb +10 -8
  29. data/spec/models/persistence.rb +5 -13
  30. data/spec/spec_helper.rb +1 -1
  31. data/spec/unit/api_spec.rb +12 -12
  32. data/spec/unit/callbacks_spec.rb +29 -45
  33. data/spec/unit/complex_example_spec.rb +15 -15
  34. data/spec/unit/event_spec.rb +89 -76
  35. data/spec/unit/guard_spec.rb +60 -0
  36. data/spec/unit/initial_state_spec.rb +4 -5
  37. data/spec/unit/inspection_spec.rb +40 -53
  38. data/spec/unit/localizer_spec.rb +22 -18
  39. data/spec/unit/new_dsl_spec.rb +2 -2
  40. data/spec/unit/persistence/active_record_persistence_spec.rb +111 -89
  41. data/spec/unit/persistence/mongoid_persistance_spec.rb +102 -81
  42. data/spec/unit/simple_example_spec.rb +20 -21
  43. data/spec/unit/state_spec.rb +16 -16
  44. data/spec/unit/subclassing_spec.rb +8 -8
  45. data/spec/unit/transition_spec.rb +59 -44
  46. metadata +28 -94
  47. data/lib/aasm/deprecated/aasm.rb +0 -15
  48. data/spec/models/callback_old_dsl.rb +0 -41
  49. data/spec/schema.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a95f430c49bb639c7f0df66dc4ce2998636ef6a
4
- data.tar.gz: 67293708b7b6fbaae038e97d229367d0ca074aa8
3
+ metadata.gz: 624aadcd0801dd7a8fb367c00d29ea7f5dccd6f3
4
+ data.tar.gz: 8f4d0f3978038a5a16fbe2696efbb1bb1f173603
5
5
  SHA512:
6
- metadata.gz: 90707f9d64e5e03e9b58acde6081c9fe5239ff5599ece71a1909abad871dfdb99dfe8d1d63fae89a94d6f5a908754649387cb792f150d09a94f3a3acab2f2714
7
- data.tar.gz: 20f34ec847d1fe22c59a7e077c5ccdd54f5ab6483dbab086544c7f7995f8df408a018344248ed9017ce9f8ed23f5d64dfe549855700d68c8797911edae9ceafc
6
+ metadata.gz: 9359ea9f090c25f5ae789f3ef47e3ad8829ebf7074e23cb9fee9738537f9207e96a9c5e6ddbbe592c02b2d80aac18df7673aa3427735b0766b6e9a34d4c62dd9
7
+ data.tar.gz: ddbfc65e9019d92b165f75ebf170c68682e829ed969d9c743df02dabaa03bc53ca6397d5d5b3bb5a8ebe66cae53621cefd8f74bffc4890536638112a6856bf88
data/.gitignore CHANGED
@@ -6,8 +6,11 @@ coverage
6
6
  pkg
7
7
  rdoc
8
8
  Gemfile.lock
9
+ gemfiles/*.lock
9
10
  spec/debug.log
10
11
  spec/*.db
11
12
  TODO
12
13
  .rvmrc
14
+ .ruby-version
15
+ .ruby-gemset
13
16
  alto
data/.travis.yml CHANGED
@@ -1,11 +1,30 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
- - 1.8.7
4
+ # - 1.8.7
4
5
  - 1.9.2
5
6
  - 1.9.3
6
7
  - 2.0.0
8
+ - 2.1.0
7
9
  # - jruby-18mode # JRuby in 1.8 mode
8
- # - jruby-19mode # JRuby in 1.9 mode
9
- - rbx-18mode
10
- - rbx-19mode
10
+ - jruby-19mode # JRuby in 1.9 mode
11
+ - rbx-2.2.1
12
+
11
13
  services: mongodb
14
+
15
+ gemfile:
16
+ - gemfiles/rails_3.2.gemfile
17
+ - gemfiles/rails_4.0.gemfile
18
+ - gemfiles/rails_4.1.gemfile
19
+
20
+ matrix:
21
+ allow_failures:
22
+ - rvm: rbx-2.2.1
23
+ - rvm: jruby-19mode
24
+ exclude:
25
+ - { rvm: 1.8.7, gemfile: gemfiles/rails_4.0.gemfile }
26
+ - { rvm: 1.8.7, gemfile: gemfiles/rails_4.1.gemfile }
27
+ - { rvm: 1.9.2, gemfile: gemfiles/rails_4.0.gemfile }
28
+ - { rvm: 1.9.2, gemfile: gemfiles/rails_4.1.gemfile }
29
+ - { rvm: 1.9.3, gemfile: gemfiles/rails_4.1.gemfile }
30
+ - { rvm: jruby-19mode, gemfile: gemfiles/rails_4.1.gemfile }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.9.0 (not yet released)
4
+
5
+ * deprecated old aasm_* class methods (old-style DSL), in preparation for AASM v4.0.0
6
+
7
+ ## 3.1.0
8
+
9
+ * validating the current state (see [issue #95](https://github.com/aasm/aasm/issues/95), thanks to [@ivantsepp](https://github.com/ivantsepp))
10
+ * allow configuring behavior of nested transactions (see [issue #107](https://github.com/aasm/aasm/issues/107))
11
+ * support multiple guards per transition
12
+ * support event guards (see [issue #85](https://github.com/aasm/aasm/issues/85))
13
+ * support reading from- and to-state during on_transition callback (see [issue #100](https://github.com/aasm/aasm/issues/100))
14
+
15
+ ## 3.0.26
16
+
17
+ * support state.human_name (aliased to state.localized_name) (see [issue #105](https://github.com/aasm/aasm/issues/105))
18
+
19
+ ## 3.0.25
20
+
21
+ * initialize the state even if validation is skipped (for ActiveRecord and Mongoid persistence) (see [issue #103](https://github.com/aasm/aasm/issues/103), thanks to [@vfonic](https://github.com/vfonic) and [@aaronklaassen](https://github.com/aaronklaassen))
22
+
3
23
  ## 3.0.24
4
24
 
5
25
  * added support for event blocks (thanks to [@Intrepidd](https://github.com/Intrepidd))
data/Gemfile CHANGED
@@ -1,3 +1,11 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls", :platforms => :ruby
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem "jruby-openssl", :platforms => :jruby
7
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
8
+ gem "rails", "3.2.15"
9
+ gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
2
10
 
3
11
  gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2012 Scott Barron
1
+ Copyright (c) 2006-2014 Scott Barron
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # AASM - Ruby state machines
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/aasm.png)](http://badge.fury.io/rb/aasm) [![Build Status](https://secure.travis-ci.org/aasm/aasm.png?branch=master)](http://travis-ci.org/aasm/aasm) [![Code Climate](https://codeclimate.com/github/aasm/aasm.png)](https://codeclimate.com/github/aasm/aasm) [![Coverage Status](https://coveralls.io/repos/aasm/aasm/badge.png?branch=master)](https://coveralls.io/r/aasm/aasm)
3
+ <a href="http://badge.fury.io/rb/aasm"><img src="https://badge.fury.io/rb/aasm@2x.png" alt="Gem Version" height="18"></a>
4
+ [![Build Status](https://secure.travis-ci.org/aasm/aasm.png?branch=master)](http://travis-ci.org/aasm/aasm)
5
+ [![Code Climate](https://codeclimate.com/github/aasm/aasm.png)](https://codeclimate.com/github/aasm/aasm)
6
+ [![Coverage Status](https://coveralls.io/repos/aasm/aasm/badge.png?branch=master)](https://coveralls.io/r/aasm/aasm)
4
7
 
5
8
  This package contains AASM, a library for adding finite state machines to Ruby classes.
6
9
 
@@ -91,7 +94,7 @@ class Job
91
94
  state :sleeping, :initial => true, :before_enter => :do_something
92
95
  state :running
93
96
 
94
- event :run, :after => Proc.new { |user| notify_somebody(user) } do
97
+ event :run, :after => Proc.new { do_afterwards } do
95
98
  transitions :from => :sleeping, :to => :running, :on_transition => Proc.new {|obj, *args| obj.set_process(*args) }
96
99
  end
97
100
 
@@ -114,7 +117,7 @@ class Job
114
117
  ...
115
118
  end
116
119
 
117
- def notify_somebody(user)
120
+ def do_afterwards
118
121
  ...
119
122
  end
120
123
 
@@ -122,7 +125,7 @@ end
122
125
  ```
123
126
 
124
127
  In this case `do_something` is called before actually entering the state `sleeping`,
125
- while `notify_somebody` is called after the transition `run` (from `sleeping` to `running`)
128
+ while `do_afterwards` is called after the transition `run` (from `sleeping` to `running`)
126
129
  is finished.
127
130
 
128
131
  Here you can see a list of all possible callbacks, together with their order of calling:
@@ -149,6 +152,15 @@ In this case the `set_process` would be called with `:defagmentation` argument.
149
152
  In case of an error during the event processing the error is rescued and passed to `:error`
150
153
  callback, which can handle it or re-raise it for further propagation.
151
154
 
155
+ During the `:on_transition` callback (and reliably only then) you can access the
156
+ originating state (the from-state) and the target state (the to state), like this:
157
+
158
+ ```ruby
159
+ def set_process(name)
160
+ logger.info "from #{aasm.from_state} to #{aasm.to_state}"
161
+ end
162
+ ```
163
+
152
164
  ### Guards
153
165
 
154
166
  Let's assume you want to allow particular transitions only if a defined condition is
@@ -190,6 +202,24 @@ job.may_sleep? # => false
190
202
  job.sleep # => raises AASM::InvalidTransition
191
203
  ```
192
204
 
205
+ You can even provide a number of guards, which all have to succeed to proceed
206
+
207
+ ```ruby
208
+ def walked_the_dog?; ...; end
209
+
210
+ event :sleep do
211
+ transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?, :walked_the_dog?]
212
+ end
213
+ ```
214
+
215
+ If you want to provide guards for all transitions withing an event, you can use event guards
216
+
217
+ ```ruby
218
+ event :sleep, :guards => [:walked_the_dog?] do
219
+ transitions :from => :running, :to => :sleeping, :guards => [:cleaning_needed?]
220
+ transitions :from => :cleaning, :to => :sleeping
221
+ end
222
+ ```
193
223
 
194
224
  ### ActiveRecord
195
225
 
@@ -257,6 +287,7 @@ to include Mongoid::Document before you include AASM.
257
287
  class Job
258
288
  include Mongoid::Document
259
289
  include AASM
290
+ field :aasm_state
260
291
  aasm do
261
292
  ...
262
293
  end
@@ -325,9 +356,9 @@ class Job < ActiveRecord::Base
325
356
 
326
357
  aasm do
327
358
  state :sleeping, :initial => true
328
- state :running
359
+ state :running, :after_commit => :notify_about_running_job
329
360
 
330
- event :run, :after_commit => :notify_about_running_job do
361
+ event :run do
331
362
  transitions :from => :sleeping, :to => :running
332
363
  end
333
364
  end
@@ -338,6 +369,28 @@ class Job < ActiveRecord::Base
338
369
  end
339
370
  ```
340
371
 
372
+ If you want to encapsulate state changes within an own transaction, the behavior
373
+ of this nested transaction might be confusing. Take a look at
374
+ [ActiveRecord Nested Transactions](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)
375
+ if you want to know more about this. Nevertheless, AASM by default requires a new transaction
376
+ `transaction(:requires_new => true)`. You can override this behavior by changing
377
+ the configuration
378
+
379
+ ```ruby
380
+ class Job < ActiveRecord::Base
381
+ include AASM
382
+
383
+ aasm :requires_new_transaction => false do
384
+ ...
385
+ end
386
+
387
+ ...
388
+ end
389
+ ```
390
+
391
+ which then leads to `transaction(:requires_new => false)`, the Rails default.
392
+
393
+
341
394
  ### Column name & migration
342
395
 
343
396
  As a default AASM uses the column `aasm_state` to store the states. You can override
@@ -417,7 +470,7 @@ gem 'aasm'
417
470
 
418
471
  ## Latest changes ##
419
472
 
420
- Look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details.
473
+ Take a look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details about recent changes to the current version.
421
474
 
422
475
  ## Questions? ##
423
476
 
@@ -427,11 +480,11 @@ Feel free to
427
480
  * [ask a question on StackOverflow](http://stackoverflow.com) (tag with `aasm`)
428
481
  * send us a tweet [@aasm](http://twitter.com/aasm)
429
482
 
430
- ## Authors ##
483
+ ## Maintainers ##
431
484
 
432
- * [Scott Barron](https://github.com/rubyist)
433
- * [Travis Tilley](https://github.com/ttilley)
434
- * [Thorsten Böttger](http://github.com/alto)
485
+ * [Scott Barron](https://github.com/rubyist) (2006–2009, original author)
486
+ * [Travis Tilley](https://github.com/ttilley) (2009–2011)
487
+ * [Thorsten Böttger](http://github.com/alto) (since 2011)
435
488
 
436
489
 
437
490
  ## Warranty ##
@@ -443,7 +496,7 @@ purpose.
443
496
 
444
497
  ## License ##
445
498
 
446
- Copyright (c) 2006-2012 Scott Barron
499
+ Copyright (c) 2006-2014 Scott Barron
447
500
 
448
501
  Permission is hereby granted, free of charge, to any person obtaining
449
502
  a copy of this software and associated documentation files (the
data/aasm.gemspec CHANGED
@@ -13,22 +13,21 @@ Gem::Specification.new do |s|
13
13
  s.date = Time.now
14
14
  s.licenses = ["MIT"]
15
15
 
16
- s.add_development_dependency 'activerecord', '3.2.15'
16
+ # s.add_development_dependency 'activerecord', '3.2.15'
17
17
  # s.add_development_dependency 'activerecord', '4.0.1'
18
18
 
19
- s.add_development_dependency 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
19
+ # s.add_development_dependency 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
20
20
  s.add_development_dependency 'rake'
21
21
  s.add_development_dependency 'sdoc'
22
- s.add_development_dependency 'rspec', '~> 2.14'
22
+ s.add_development_dependency 'rspec', '>= 2.14'
23
23
  s.add_development_dependency 'rr'
24
- s.add_development_dependency 'sqlite3'
24
+ # s.add_development_dependency 'sqlite3'
25
25
  s.add_development_dependency 'minitest'
26
26
  # s.add_development_dependency 'debugger'
27
27
  # s.add_development_dependency 'pry'
28
- s.add_development_dependency 'ruby-debug-completion'
29
28
 
30
29
  s.add_development_dependency 'mime-types', '~> 1.25' # needed by coveralls (>= 2.0 needs Ruby >=1.9.2)
31
- s.add_development_dependency 'coveralls'
30
+ # s.add_development_dependency 'coveralls'
32
31
 
33
32
  s.files = `git ls-files`.split("\n")
34
33
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "3.2.16"
10
+ gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
11
+
12
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.0.2"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.1.0.beta1"
10
+
11
+ gemspec :path => "../"
data/lib/aasm/aasm.rb CHANGED
@@ -26,52 +26,56 @@ module AASM
26
26
  @aasm
27
27
  end
28
28
 
29
- # TODO: maybe better: aasm.initial_state
29
+ # TODO remove this method in v4.0.0
30
30
  def aasm_initial_state(set_state=nil)
31
31
  if set_state
32
- # deprecated way to set the value
32
+ warn ".aasm_initial_state(:name) is deprecated and will be removed in version 4.0.0; please use .aasm.initial_state = :name instead!"
33
33
  AASM::StateMachine[self].initial_state = set_state
34
34
  else
35
+ warn ".aasm_initial_state is deprecated and will be removed in version 4.0.0; please use .aasm.initial_state instead!"
35
36
  AASM::StateMachine[self].initial_state
36
37
  end
37
38
  end
38
39
 
39
- # is this better?: aasm.states.name.from_states
40
+ # TODO remove this method in v4.0.0
40
41
  def aasm_from_states_for_state(state, options={})
41
- if options[:transition]
42
- aasm.events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
43
- else
44
- aasm.events.map {|k,v| v.transitions_to_state(state)}.flatten.map(&:from).flatten
45
- end
42
+ warn ".aasm_from_states_for_state is deprecated and will be removed in version 4.0.0; please use .aasm.from_states_for_state instead!"
43
+ aasm.from_states_for_state(state, options)
46
44
  end
47
45
 
48
- # deprecated
46
+ # TODO remove this method in v4.0.0
49
47
  def aasm_initial_state=(state)
48
+ warn ".aasm_initial_state= is deprecated and will be removed in version 4.0.0"
50
49
  AASM::StateMachine[self].initial_state = state
51
50
  end
52
51
 
53
- # deprecated
52
+ # TODO remove this method in v4.0.0
54
53
  def aasm_state(name, options={})
54
+ warn ".aasm_state is deprecated and will be removed in version 4.0.0; please use .aasm.state instead!"
55
55
  aasm.state(name, options)
56
56
  end
57
57
 
58
- # deprecated
58
+ # TODO remove this method in v4.0.0
59
59
  def aasm_event(name, options = {}, &block)
60
+ warn ".aasm_event is deprecated and will be removed in version 4.0.0; please use .aasm.event instead!"
60
61
  aasm.event(name, options, &block)
61
62
  end
62
63
 
63
- # deprecated
64
+ # TODO remove this method in v4.0.0
64
65
  def aasm_states
66
+ warn ".aasm_states is deprecated and will be removed in version 4.0.0; please use .aasm.states instead!"
65
67
  aasm.states
66
68
  end
67
69
 
68
- # deprecated
70
+ # TODO remove this method in v4.0.0
69
71
  def aasm_events
72
+ warn ".aasm_events is deprecated and will be removed in version 4.0.0; please use .aasm.events instead!"
70
73
  aasm.events
71
74
  end
72
75
 
73
- # deprecated
76
+ # TODO remove this method in v4.0.0
74
77
  def aasm_states_for_select
78
+ warn ".aasm_states_for_select is deprecated and will be removed in version 4.0.0; please use .aasm.states_for_select instead!"
75
79
  aasm.states_for_select
76
80
  end
77
81
 
@@ -103,46 +107,46 @@ module AASM
103
107
  true
104
108
  end
105
109
 
106
- # deprecated
110
+ # TODO remove this method in v4.0.0
107
111
  def aasm_current_state
108
- # warn "#aasm_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.state instead!"
112
+ warn "#aasm_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.current_state instead!"
109
113
  aasm.current_state
110
114
  end
111
115
 
112
- # deprecated
116
+ # TODO remove this method in v4.0.0
113
117
  def aasm_enter_initial_state
114
- # warn "#aasm_enter_initial_state is deprecated and will be removed in version 3.2.0; please use #aasm.enter_initial_state instead!"
118
+ warn "#aasm_enter_initial_state is deprecated and will be removed in version 4.0.0; please use #aasm.enter_initial_state instead!"
115
119
  aasm.enter_initial_state
116
120
  end
117
121
 
118
- # deprecated
122
+ # TODO remove this method in v4.0.0
119
123
  def aasm_events_for_current_state
120
- # warn "#aasm_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.events instead!"
124
+ warn "#aasm_events_for_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.events(aasm.current_state) instead!"
121
125
  aasm.events(aasm.current_state)
122
126
  end
123
127
 
124
- # deprecated
128
+ # TODO remove this method in v4.0.0
125
129
  def aasm_permissible_events_for_current_state
126
- # warn "#aasm_permissible_events_for_current_state is deprecated and will be removed in version 3.2.0; please use #aasm.permissible_events instead!"
130
+ warn "#aasm_permissible_events_for_current_state is deprecated and will be removed in version 4.0.0; please use #aasm.permissible_events instead!"
127
131
  aasm.permissible_events
128
132
  end
129
133
 
130
- # deprecated
134
+ # TODO remove this method in v4.0.0
131
135
  def aasm_events_for_state(state_name)
132
- # warn "#aasm_events_for_state(state_name) is deprecated and will be removed in version 3.2.0; please use #aasm.events(state_name) instead!"
136
+ warn "#aasm_events_for_state(state_name) is deprecated and will be removed in version 4.0.0; please use #aasm.events(state_name) instead!"
133
137
  aasm.events(state_name)
134
138
  end
135
139
 
136
- # deprecated
140
+ # TODO remove this method in v4.0.0
137
141
  def aasm_human_state
138
- # warn "#aasm_human_state is deprecated and will be removed in version 3.2.0; please use #aasm.human_state instead!"
142
+ warn "#aasm_human_state is deprecated and will be removed in version 4.0.0; please use #aasm.human_state instead!"
139
143
  aasm.human_state
140
144
  end
141
145
 
142
146
  private
143
147
 
144
148
  def aasm_fire_event(event_name, options, *args, &block)
145
- event = self.class.aasm_events[event_name]
149
+ event = self.class.aasm.events[event_name]
146
150
  begin
147
151
  old_state = aasm.state_object_for_name(aasm.current_state)
148
152
  old_state.fire_callbacks(:exit, self)
data/lib/aasm/base.rb CHANGED
@@ -5,33 +5,31 @@ module AASM
5
5
  @clazz = clazz
6
6
  @state_machine = AASM::StateMachine[@clazz]
7
7
  @state_machine.config.column = options[:column].to_sym if options[:column]
8
+ @options = options
8
9
 
9
- if options.key?(:whiny_transitions)
10
- @state_machine.config.whiny_transitions = options[:whiny_transitions]
11
- elsif @state_machine.config.whiny_transitions.nil?
12
- @state_machine.config.whiny_transitions = true # this is the default, so let's cry
13
- end
10
+ # let's cry if the transition is invalid
11
+ configure :whiny_transitions, true
14
12
 
15
- if options.key?(:create_scopes)
16
- @state_machine.config.create_scopes = options[:create_scopes]
17
- elsif @state_machine.config.create_scopes.nil?
18
- @state_machine.config.create_scopes = true # this is the default, so let's create scopes
19
- end
13
+ # create named scopes for each state
14
+ configure :create_scopes, true
20
15
 
21
- if options.key?(:skip_validation_on_save)
22
- @state_machine.config.skip_validation_on_save = options[:skip_validation_on_save]
23
- elsif @state_machine.config.skip_validation_on_save.nil?
24
- @state_machine.config.skip_validation_on_save = false # this is the default, so don't store any new state if the model is invalid
25
- end
16
+ # don't store any new state if the model is invalid
17
+ configure :skip_validation_on_save, false
18
+
19
+ # use requires_new for nested transactions
20
+ configure :requires_new_transaction, true
26
21
  end
27
22
 
28
- def initial_state
29
- @state_machine.initial_state
23
+ def initial_state(new_initial_state=nil)
24
+ if new_initial_state
25
+ @state_machine.initial_state = new_initial_state
26
+ else
27
+ @state_machine.initial_state
28
+ end
30
29
  end
31
30
 
32
31
  # define a state
33
32
  def state(name, options={})
34
- # @clazz.aasm_state(name, options)
35
33
  @state_machine.add_state(name, @clazz, options)
36
34
  @state_machine.initial_state = name if options[:initial] || !@state_machine.initial_state
37
35
 
@@ -46,8 +44,6 @@ module AASM
46
44
 
47
45
  # define an event
48
46
  def event(name, options={}, &block)
49
- # @clazz.aasm_event(name, options, &block)
50
-
51
47
  @state_machine.events[name] = AASM::Event.new(name, options, &block)
52
48
 
53
49
  # an addition over standard aasm so that, before firing an event, you can ask
@@ -78,5 +74,24 @@ module AASM
78
74
  states.map { |state| state.for_select }
79
75
  end
80
76
 
77
+ def from_states_for_state(state, options={})
78
+ if options[:transition]
79
+ events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
80
+ else
81
+ events.map {|k,v| v.transitions_to_state(state)}.flatten.map(&:from).flatten
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def configure(key, default_value)
88
+ @state_machine.config.send(:new_ostruct_member, key)
89
+ if @options.key?(key)
90
+ @state_machine.config.send("#{key}=", @options[key])
91
+ elsif @state_machine.config.send(key).nil?
92
+ @state_machine.config.send("#{key}=", default_value)
93
+ end
94
+ end
95
+
81
96
  end
82
97
  end
data/lib/aasm/event.rb CHANGED
@@ -6,6 +6,7 @@ module AASM
6
6
  def initialize(name, options = {}, &block)
7
7
  @name = name
8
8
  @transitions = []
9
+ @guards = Array(options[:guard] || options[:guards])
9
10
  update(options, &block)
10
11
  end
11
12
 
@@ -36,9 +37,9 @@ module AASM
36
37
  @transitions.select { |t| t.to == state }
37
38
  end
38
39
 
39
- # deprecated
40
+ # TODO remove this method in v4.0.0
40
41
  def all_transitions
41
- # warn "Event#all_transitions is deprecated and will be removed in version 3.2.0; please use Event#transitions instead!"
42
+ warn "Event#all_transitions is deprecated and will be removed in version 4.0.0; please use Event#transitions instead!"
42
43
  transitions
43
44
  end
44
45
 
@@ -54,8 +55,31 @@ module AASM
54
55
  end
55
56
  end
56
57
 
58
+ ## DSL interface
59
+ def transitions(definitions=nil)
60
+ if definitions # define new transitions
61
+ # Create a separate transition for each from-state to the given state
62
+ Array(definitions[:from]).each do |s|
63
+ @transitions << AASM::Transition.new(attach_event_guards(definitions.merge(:from => s.to_sym)))
64
+ end
65
+ # Create a transition if :to is specified without :from (transitions from ANY state)
66
+ if @transitions.empty? && definitions[:to]
67
+ @transitions << AASM::Transition.new(attach_event_guards(definitions))
68
+ end
69
+ end
70
+ @transitions
71
+ end
72
+
57
73
  private
58
74
 
75
+ def attach_event_guards(definitions)
76
+ unless @guards.empty?
77
+ given_guards = Array(definitions.delete(:guard) || definitions.delete(:guards))
78
+ definitions[:guards] = given_guards + @guards
79
+ end
80
+ definitions
81
+ end
82
+
59
83
  def update(options = {}, &block)
60
84
  @options = options
61
85
  if block then
@@ -68,7 +92,7 @@ module AASM
68
92
  def _fire(obj, test, to_state=nil, *args)
69
93
  result = test ? false : nil
70
94
  if @transitions.map(&:from).any?
71
- transitions = @transitions.select { |t| t.from == obj.aasm_current_state }
95
+ transitions = @transitions.select { |t| t.from == obj.aasm.current_state }
72
96
  return result if transitions.size == 0
73
97
  else
74
98
  transitions = @transitions
@@ -106,19 +130,6 @@ module AASM
106
130
  end
107
131
  end
108
132
 
109
- ## DSL interface
110
- def transitions(trans_opts=nil)
111
- if trans_opts # define new transitions
112
- # Create a separate transition for each from state to the given state
113
- Array(trans_opts[:from]).each do |s|
114
- @transitions << AASM::Transition.new(trans_opts.merge({:from => s.to_sym}))
115
- end
116
- # Create a transition if to is specified without from (transitions from ANY state)
117
- @transitions << AASM::Transition.new(trans_opts) if @transitions.empty? && trans_opts[:to]
118
- end
119
- @transitions
120
- end
121
-
122
133
  [:after, :before, :error, :success].each do |callback_name|
123
134
  define_method callback_name do |*args, &block|
124
135
  options[callback_name] = Array(options[callback_name])
@@ -1,6 +1,8 @@
1
1
  module AASM
2
2
  class InstanceBase
3
3
 
4
+ attr_accessor :from_state, :to_state
5
+
4
6
  def initialize(instance)
5
7
  @instance = instance
6
8
  end
@@ -15,7 +17,7 @@ module AASM
15
17
  end
16
18
 
17
19
  def enter_initial_state
18
- state_name = determine_state_name(@instance.class.aasm_initial_state)
20
+ state_name = determine_state_name(@instance.class.aasm.initial_state)
19
21
  state_object = state_object_for_name(state_name)
20
22
 
21
23
  state_object.fire_callbacks(:before_enter, @instance)