aasm 4.9.0 → 4.10.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -4
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +3 -0
  5. data/README.md +27 -11
  6. data/gemfiles/rails_4.0.gemfile +1 -0
  7. data/gemfiles/rails_4.1.gemfile +1 -0
  8. data/gemfiles/rails_4.2_mongo_mapper.gemfile +1 -0
  9. data/lib/aasm.rb +3 -1
  10. data/lib/aasm/aasm.rb +13 -9
  11. data/lib/aasm/base.rb +67 -28
  12. data/lib/aasm/configuration.rb +3 -0
  13. data/lib/aasm/core/event.rb +8 -1
  14. data/lib/aasm/core/transition.rb +32 -4
  15. data/lib/aasm/errors.rb +4 -4
  16. data/lib/aasm/persistence.rb +14 -1
  17. data/lib/aasm/persistence/active_record_persistence.rb +27 -13
  18. data/lib/aasm/persistence/base.rb +2 -44
  19. data/lib/aasm/persistence/core_data_query_persistence.rb +93 -0
  20. data/lib/aasm/persistence/dynamoid_persistence.rb +2 -4
  21. data/lib/aasm/persistence/mongo_mapper_persistence.rb +15 -9
  22. data/lib/aasm/persistence/mongoid_persistence.rb +24 -4
  23. data/lib/aasm/persistence/redis_persistence.rb +107 -0
  24. data/lib/aasm/persistence/sequel_persistence.rb +1 -3
  25. data/lib/aasm/state_machine.rb +1 -9
  26. data/lib/aasm/state_machine_store.rb +73 -0
  27. data/lib/aasm/version.rb +1 -1
  28. data/lib/generators/active_record/templates/migration_existing.rb +2 -6
  29. data/lib/motion-aasm.rb +35 -0
  30. data/spec/models/callbacks/basic.rb +12 -2
  31. data/spec/models/callbacks/guard_within_block.rb +2 -1
  32. data/spec/models/callbacks/multiple_transitions_transition_guard.rb +2 -1
  33. data/spec/models/callbacks/with_args.rb +2 -1
  34. data/spec/models/callbacks/with_state_arg.rb +6 -2
  35. data/spec/models/mongoid/mongoid_relationships.rb +26 -0
  36. data/spec/models/namespaced_multiple_example.rb +28 -0
  37. data/spec/models/parametrised_event.rb +9 -3
  38. data/spec/models/states_on_one_line_example.rb +8 -0
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/unit/api_spec.rb +20 -0
  41. data/spec/unit/callbacks_spec.rb +17 -5
  42. data/spec/unit/event_spec.rb +19 -1
  43. data/spec/unit/exception_spec.rb +11 -0
  44. data/spec/unit/memory_leak_spec.rb +1 -1
  45. data/spec/unit/namespaced_multiple_example_spec.rb +53 -0
  46. data/spec/unit/override_warning_spec.rb +43 -0
  47. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +1 -1
  48. data/spec/unit/persistence/active_record_persistence_spec.rb +1 -1
  49. data/spec/unit/persistence/mongoid_persistence_spec.rb +11 -0
  50. data/spec/unit/persistence/redis_persistence_spec.rb +77 -0
  51. data/spec/unit/readme_spec.rb +1 -2
  52. data/spec/unit/states_on_one_line_example_spec.rb +16 -0
  53. data/spec/unit/transition_spec.rb +60 -1
  54. metadata +22 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4a393ed849111b8beee789a849433679c36f940
4
- data.tar.gz: 905f16c76e62d5481bcfe55f4bb935039b0c7726
3
+ metadata.gz: 0a36f037200d0d9577fe0164fdd7a66e23db9156
4
+ data.tar.gz: 253250812a0f774df4e1d0c5111bf6c273ccd76d
5
5
  SHA512:
6
- metadata.gz: 1e64e9fffd9c560a166ab728105d3891ca9a6a8784c27b70f83d9fd91ed7ccde1c839662f8e7e099ef4128db6bc91a690a30c8fbb3c0f83e4bfeba7d2c0ad67f
7
- data.tar.gz: 574cafabbe8b20e1bf9db7ef87ff10c358dd814fd3bc86fc2f843824c9be8deb4ad645c9a0273a7ecf861bfb6136b519476f1b749a0d3706e798b24a3dd92da8
6
+ metadata.gz: b41ce1fa467ee74ec16d1e3260506adfbda581d13078f2548120e4322c6a1582fb93aae9c84b451e834cd621ce115a3bb6f75c57a7b09be598fc93d2a348f919
7
+ data.tar.gz: c43910a1666f9011dfe6b604f6626931c821f5a2e5d9f641194e1837a5eb0b3a000f5d85cfca24af60635dec36074f3df9c83bbcd552b4e7da0da6b00d323e9d
@@ -3,18 +3,18 @@ language: ruby
3
3
  cache: bundler
4
4
 
5
5
  rvm:
6
- # - 1.8.7
7
- # - 1.9.2
8
6
  - 1.9.3
9
7
  - 2.0.0
10
8
  - 2.1
11
9
  - 2.2
12
- # - jruby-18mode # JRuby in 1.8 mode
10
+ - 2.3
13
11
  - jruby-1.7 # JRuby in 1.9 mode
14
12
  - jruby-9.0.4.0
15
13
  - rbx-2.5.8
16
14
 
17
- services: mongodb
15
+ services:
16
+ - mongodb
17
+ - redis-server
18
18
 
19
19
  gemfile:
20
20
  - gemfiles/rails_3.2_stable.gemfile
@@ -35,8 +35,13 @@ matrix:
35
35
  allow_failures:
36
36
  - rvm: rbx-2.2.1
37
37
  - rvm: jruby-1.7
38
+ - rvm: 2.3
38
39
  exclude:
39
40
  - rvm: 1.9.3
40
41
  gemfile: gemfiles/rails_4.1.gemfile
42
+ - rvm: 2.2
43
+ gemfile: gemfiles/rails_3.2_stable.gemfile
44
+ - rvm: 2.3
45
+ gemfile: gemfiles/rails_3.2_stable.gemfile
41
46
  - rvm: jruby-19mode
42
47
  gemfile: gemfiles/rails_4.1.gemfile
@@ -1,5 +1,20 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 4.10.0
4
+
5
+ * fix: some issues with RubyMotion (see [issue #320](https://github.com/aasm/aasm/pull/320) and [issue #343](https://github.com/aasm/aasm/pull/343) for details, thanks to [@Infotaku](https://github.com/Infotaku))
6
+ * fix: transitions now work in dup'ed copies (see [issue #325](https://github.com/aasm/aasm/pull/325) which fixes [issue #273](https://github.com/aasm/aasm/pull/273) for details, thanks to [@lingceng](https://github.com/lingceng))
7
+ * fix: allow skipping the `aasm_ensure_initial_state` callback (see [issue #326](https://github.com/aasm/aasm/pull/326) for details, thanks to [@sineed](https://github.com/sineed))
8
+ * fix: has_many association helper works again for Mongoid (see [issue #333](https://github.com/aasm/aasm/pull/333) which fixes [issue #332](https://github.com/aasm/aasm/pull/332) for details, thanks to [@anilmaurya](https://github.com/anilmaurya))
9
+ * improve performance / refactor: load and run only code which is needed (see [issue #336](https://github.com/aasm/aasm/pull/336) for details, thanks to [@csmuc](https://github.com/csmuc))
10
+ * improve: warn when overriding an existing method (see [issue #340](https://github.com/aasm/aasm/pull/340) which fixes [issue #335](https://github.com/aasm/aasm/pull/335) for details, thanks to [@pirj](https://github.com/pirj))
11
+ * fix: correct error message (by not evaluating the current state lazily) (see [issue #341](https://github.com/aasm/aasm/pull/341) which fixes [issue #312](https://github.com/aasm/aasm/pull/312) for details, thanks to [@pirj](https://github.com/pirj))
12
+ * addition: support for Redis as persistence layer (see [issue #190](https://github.com/aasm/aasm/pull/190) for details, thanks to [@javajax](https://github.com/javajax))
13
+ * addition: support transition `:success` callbacks (see [issue #239](https://github.com/aasm/aasm/pull/239) which fixes [issue #236](https://github.com/aasm/aasm/pull/236) for details, thanks to [@brega](https://github.com/brega))
14
+ * addition: support for namespacing methods and state names (see [issue #259](https://github.com/aasm/aasm/pull/259) for details, thanks to [@allspiritseve](https://github.com/allspiritseve))
15
+ * addition: support for defining multiple states in one line (see [issue #288](https://github.com/aasm/aasm/pull/288) which fixes [issue #146](https://github.com/aasm/aasm/pull/146) for details, thanks to [@HParker](https://github.com/HParker))
16
+ * fix: uninitialised constant when running Rails generator (see [issue #339](https://github.com/aasm/aasm/pull/339) for details, thanks to [@long-long-float](https://github.com/long-long-float))
17
+
3
18
  ## 4.9.0
4
19
 
5
20
  * add support for callback classes (`after` only) (see [issue #316](https://github.com/aasm/aasm/pull/316) for details, thanks to [@mlr](https://github.com/mlr))
data/Gemfile CHANGED
@@ -17,4 +17,7 @@ gem 'sequel'
17
17
  # gem 'mongo_mapper', '~> 0.13'
18
18
  # gem 'bson_ext', :platforms => :ruby
19
19
 
20
+ # uncomment if you want to run specs for Redis persistence
21
+ # gem "redis-objects"
22
+
20
23
  gemspec
data/README.md CHANGED
@@ -28,8 +28,7 @@ class Job
28
28
 
29
29
  aasm do
30
30
  state :sleeping, :initial => true
31
- state :running
32
- state :cleaning
31
+ state :running, :cleaning
33
32
 
34
33
  event :run do
35
34
  transitions :from => :sleeping, :to => :running
@@ -97,6 +96,7 @@ class Job
97
96
  aasm do
98
97
  state :sleeping, :initial => true, :before_enter => :do_something
99
98
  state :running
99
+ state :finished
100
100
 
101
101
  after_all_transitions :log_status_change
102
102
 
@@ -149,7 +149,7 @@ In this case `do_something` is called before actually entering the state `sleepi
149
149
  while `notify_somebody` is called after the transition `run` (from `sleeping` to `running`)
150
150
  is finished.
151
151
 
152
- AASM will also initialize `LogRunTime` and run the `call` method for you after the transition from `runnung` to `finished` in the example above. You can pass arguments to the class by defining an initialize method on it, like this:
152
+ AASM will also initialize `LogRunTime` and run the `call` method for you after the transition from `running` to `finished` in the example above. You can pass arguments to the class by defining an initialize method on it, like this:
153
153
 
154
154
  ```
155
155
  class LogRunTime
@@ -158,7 +158,7 @@ class LogRunTime
158
158
  def initialize(job, args = {})
159
159
  @job = job
160
160
  end
161
-
161
+
162
162
  def call
163
163
  log "Job was running for #{@job.run_time} seconds"
164
164
  end
@@ -180,7 +180,8 @@ begin
180
180
  new_state before_enter
181
181
  new_state enter
182
182
  ...update state...
183
- event success # if persist successful
183
+ transition success # if persist successful
184
+ event success # if persist successful
184
185
  old_state after_exit
185
186
  new_state after_enter
186
187
  event after
@@ -404,7 +405,7 @@ simple.aasm(:work).current
404
405
 
405
406
  _AASM_ doesn't prohibit to define the same event in more than one state machine. The
406
407
  latest definition "wins" and overrides previous definitions. Nonetheless, a warning is issued:
407
- `SimpleMultipleExample: The aasm event name run is already used!`.
408
+ `SimpleMultipleExample: overriding method 'run'!`.
408
409
 
409
410
  All _AASM_ class- and instance-level `aasm` methods accept a state machine selector.
410
411
  So, for example, to use inspection on a class level, you have to use
@@ -423,7 +424,7 @@ AASM allows you to easily extend `AASM::Base` for your own application purposes.
423
424
 
424
425
  Let's suppose we have common logic across many AASM models. We can embody this logic in a sub-class of `AASM::Base`.
425
426
 
426
- ```
427
+ ```ruby
427
428
  class CustomAASMBase < AASM::Base
428
429
  # A custom transiton that we want available across many AASM models.
429
430
  def count_transitions!
@@ -460,7 +461,7 @@ end
460
461
 
461
462
  When we declare our model that has an AASM state machine, we simply declare the AASM block with a `:with` key to our own class.
462
463
 
463
- ```
464
+ ```ruby
464
465
  class SimpleCustomExample
465
466
  include AASM
466
467
 
@@ -662,6 +663,21 @@ class Job
662
663
  end
663
664
  ```
664
665
 
666
+ ### Redis
667
+
668
+ AASM also supports persistence in Redis.
669
+ Make sure to include Redis::Objects before you include AASM.
670
+
671
+ ```ruby
672
+ class User
673
+ include Redis::Objects
674
+ include AASM
675
+
676
+ aasm do
677
+ end
678
+ end
679
+ ```
680
+
665
681
  ### Automatic Scopes
666
682
 
667
683
  AASM will automatically create scope methods for each state in the model.
@@ -882,11 +898,11 @@ Job.aasm.states_for_select
882
898
 
883
899
  ### RubyMotion support
884
900
 
885
- To use AASM with a RubyMotion project, use it with the [motion-bundler](https://github.com/archan937/motion-bundler) gem.
901
+ Now supports [CodeDataQuery](https://github.com/infinitered/cdq.git) !
902
+ However I'm still in the process of submitting my compatibility updates to their repository.
903
+ In the meantime you can use [my fork](https://github.com/Infotaku/cdq.git), there may still be some minor issues but I intend to extensively use it myself, so fixes should come fast.
886
904
 
887
905
  Warnings:
888
- - Due to the way key-value observation (KVO) works in iOS,
889
- you currently CANNOT use AASM with an object you are observing. (Yes.. that's pretty sad).
890
906
  - Due to RubyMotion Proc's lack of 'source_location' method, it may be harder
891
907
  to find out the origin of a "cannot transition from" error. I would recommend using
892
908
  the 'instance method symbol / string' way whenever possible when defining guardians and callbacks.
@@ -10,5 +10,6 @@ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.
10
10
  gem 'sequel'
11
11
  gem 'dynamoid', '~> 1', :platforms => :ruby
12
12
  gem 'aws-sdk', '~>2', :platforms => :ruby
13
+ gem "redis-objects"
13
14
 
14
15
  gemspec :path => "../"
@@ -10,5 +10,6 @@ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.
10
10
  gem 'sequel'
11
11
  gem 'dynamoid', '~> 1', :platforms => :ruby
12
12
  gem 'aws-sdk', '~>2', :platforms => :ruby
13
+ gem "redis-objects"
13
14
 
14
15
  gemspec :path => "../"
@@ -12,5 +12,6 @@ gem 'mongo_mapper'
12
12
  gem 'bson_ext', :platforms => :ruby
13
13
  gem 'dynamoid', '~> 1', :platforms => :ruby
14
14
  gem 'aws-sdk', '~>2', :platforms => :ruby
15
+ gem "redis-objects"
15
16
 
16
17
  gemspec :path => "../"
@@ -10,7 +10,9 @@ require 'aasm/core/transition'
10
10
  require 'aasm/core/event'
11
11
  require 'aasm/core/state'
12
12
  require 'aasm/localizer'
13
+ require 'aasm/state_machine_store'
13
14
  require 'aasm/state_machine'
14
15
  require 'aasm/persistence'
15
- require 'aasm/persistence/plain_persistence' # RubyMotion support
16
+ require 'aasm/persistence/base'
17
+ require 'aasm/persistence/plain_persistence'
16
18
  require 'aasm/aasm'
@@ -8,7 +8,7 @@ module AASM
8
8
 
9
9
  # do not overwrite existing state machines, which could have been created by
10
10
  # inheritance, see class method inherited
11
- AASM::StateMachine[base] ||= {}
11
+ AASM::StateMachineStore.register(base)
12
12
 
13
13
  AASM::Persistence.load_persistence(base)
14
14
  super
@@ -17,10 +17,8 @@ module AASM
17
17
  module ClassMethods
18
18
  # make sure inheritance (aka subclassing) works with AASM
19
19
  def inherited(base)
20
- AASM::StateMachine[base] = {}
21
- AASM::StateMachine[self].keys.each do |state_machine_name|
22
- AASM::StateMachine[base][state_machine_name] = AASM::StateMachine[self][state_machine_name].clone
23
- end
20
+ AASM::StateMachineStore.register(base, self)
21
+
24
22
  super
25
23
  end
26
24
 
@@ -36,7 +34,7 @@ module AASM
36
34
  options = args[0] || {}
37
35
  end
38
36
 
39
- AASM::StateMachine[self][state_machine_name] ||= AASM::StateMachine.new(state_machine_name)
37
+ AASM::StateMachineStore.fetch(self, true).register(state_machine_name, AASM::StateMachine.new(state_machine_name))
40
38
 
41
39
  # use a default despite the DSL configuration default.
42
40
  # this is because configuration hasn't been setup for the AASM class but we are accessing a DSL option already for the class.
@@ -55,7 +53,7 @@ module AASM
55
53
  @aasm[state_machine_name] = aasm_klass.new(
56
54
  self,
57
55
  state_machine_name,
58
- AASM::StateMachine[self][state_machine_name],
56
+ AASM::StateMachineStore.fetch(self, true).machine(state_machine_name),
59
57
  options
60
58
  )
61
59
  end
@@ -66,13 +64,18 @@ module AASM
66
64
 
67
65
  # this is the entry point for all instance-level access to AASM
68
66
  def aasm(name=:default)
69
- unless AASM::StateMachine[self.class][name.to_sym]
67
+ unless AASM::StateMachineStore.fetch(self.class, true).machine(name)
70
68
  raise AASM::UnknownStateMachineError.new("There is no state machine with the name '#{name}' defined in #{self.class.name}!")
71
69
  end
72
70
  @aasm ||= {}
73
71
  @aasm[name.to_sym] ||= AASM::InstanceBase.new(self, name.to_sym)
74
72
  end
75
73
 
74
+ def initialize_dup(other)
75
+ @aasm = {}
76
+ super
77
+ end
78
+
76
79
  private
77
80
 
78
81
  # Takes args and a from state and removes the first
@@ -147,6 +150,7 @@ private
147
150
  persist_successful = aasm(state_machine_name).set_current_state_with_persistence(new_state_name)
148
151
  if persist_successful
149
152
  yield if block_given?
153
+ event.fire_transition_callbacks(self, *process_args(event, old_state.name, *args))
150
154
  event.fire_callbacks(:success, self)
151
155
  end
152
156
  else
@@ -183,7 +187,7 @@ private
183
187
  self.aasm_event_failed(event_name, old_state.name)
184
188
  end
185
189
 
186
- if AASM::StateMachine[self.class][state_machine_name].config.whiny_transitions
190
+ if AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_transitions
187
191
  raise AASM::InvalidTransition.new(self, event_name, state_machine_name, failures)
188
192
  else
189
193
  false
@@ -1,8 +1,7 @@
1
1
  module AASM
2
2
  class Base
3
3
 
4
- attr_reader :klass,
5
- :state_machine
4
+ attr_reader :klass, :state_machine
6
5
 
7
6
  def initialize(klass, name, state_machine, options={}, &block)
8
7
  @klass = klass
@@ -38,6 +37,9 @@ module AASM
38
37
 
39
38
  configure :enum, nil
40
39
 
40
+ # Set to true to namespace reader methods and constants
41
+ configure :namespace, false
42
+
41
43
  # make sure to raise an error if no_direct_assignment is enabled
42
44
  # and attribute is directly assigned though
43
45
  aasm_name = @name
@@ -71,20 +73,29 @@ module AASM
71
73
  end
72
74
 
73
75
  # define a state
74
- def state(name, options={})
75
- @state_machine.add_state(name, klass, options)
76
-
77
- if klass.instance_methods.include?("#{name}?")
78
- warn "#{klass.name}: The aasm state name #{name} is already used!"
79
- end
80
-
81
- aasm_name = @name
82
- klass.send :define_method, "#{name}?", ->() do
83
- aasm(:"#{aasm_name}").current_state == :"#{name}"
84
- end
76
+ # args
77
+ # [0] state
78
+ # [1] options (or nil)
79
+ # or
80
+ # [0] state
81
+ # [1..] state
82
+ def state(*args)
83
+ names, options = interpret_state_args(args)
84
+ names.each do |name|
85
+ @state_machine.add_state(name, klass, options)
86
+
87
+ aasm_name = @name.to_sym
88
+ state = name.to_sym
89
+
90
+ method_name = namespace? ? "#{namespace}_#{name}" : name
91
+ safely_define_method klass, "#{method_name}?", -> do
92
+ aasm(aasm_name).current_state == state
93
+ end
85
94
 
86
- unless klass.const_defined?("STATE_#{name.upcase}")
87
- klass.const_set("STATE_#{name.upcase}", name)
95
+ const_name = namespace? ? "STATE_#{namespace.upcase}_#{name.upcase}" : "STATE_#{name.upcase}"
96
+ unless klass.const_defined?(const_name)
97
+ klass.const_set(const_name, name)
98
+ end
88
99
  end
89
100
  end
90
101
 
@@ -92,27 +103,24 @@ module AASM
92
103
  def event(name, options={}, &block)
93
104
  @state_machine.add_event(name, options, &block)
94
105
 
95
- if klass.instance_methods.include?("may_#{name}?".to_sym)
96
- warn "#{klass.name}: The aasm event name #{name} is already used!"
97
- end
106
+ aasm_name = @name.to_sym
107
+ event = name.to_sym
98
108
 
99
109
  # an addition over standard aasm so that, before firing an event, you can ask
100
110
  # may_event? and get back a boolean that tells you whether the guard method
101
111
  # on the transition will let this happen.
102
- aasm_name = @name
103
-
104
- klass.send :define_method, "may_#{name}?", ->(*args) do
105
- aasm(:"#{aasm_name}").may_fire_event?(:"#{name}", *args)
112
+ safely_define_method klass, "may_#{name}?", ->(*args) do
113
+ aasm(aasm_name).may_fire_event?(event, *args)
106
114
  end
107
115
 
108
- klass.send :define_method, "#{name}!", ->(*args, &block) do
109
- aasm(:"#{aasm_name}").current_event = :"#{name}!"
110
- aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => true}, *args, &block)
116
+ safely_define_method klass, "#{name}!", ->(*args, &block) do
117
+ aasm(aasm_name).current_event = :"#{name}!"
118
+ aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
111
119
  end
112
120
 
113
- klass.send :define_method, "#{name}", ->(*args, &block) do
114
- aasm(:"#{aasm_name}").current_event = :"#{name}"
115
- aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => false}, *args, &block)
121
+ safely_define_method klass, name, ->(*args, &block) do
122
+ aasm(aasm_name).current_event = event
123
+ aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
116
124
  end
117
125
  end
118
126
 
@@ -165,6 +173,7 @@ module AASM
165
173
  if options[:transition]
166
174
  @state_machine.events[options[:transition]].transitions_to_state(state).flatten.map(&:from).flatten
167
175
  else
176
+
168
177
  events.map {|e| e.transitions_to_state(state)}.flatten.map(&:from).flatten
169
178
  end
170
179
  end
@@ -183,5 +192,35 @@ module AASM
183
192
  end
184
193
  end
185
194
 
195
+ def safely_define_method(klass, method_name, method_definition)
196
+ if klass.instance_methods.include?(method_name.to_sym)
197
+ warn "#{klass.name}: overriding method '#{method_name}'!"
198
+ end
199
+
200
+ klass.send(:define_method, method_name, method_definition)
201
+ end
202
+
203
+ def namespace?
204
+ !!@state_machine.config.namespace
205
+ end
206
+
207
+ def namespace
208
+ if @state_machine.config.namespace == true
209
+ @name
210
+ else
211
+ @state_machine.config.namespace
212
+ end
213
+ end
214
+
215
+ def interpret_state_args(args)
216
+ if args.last.is_a?(Hash) && args.size == 2
217
+ [[args.first], args.last]
218
+ elsif args.size > 0
219
+ [args, {}]
220
+ else
221
+ raise "count not parse states: #{args}"
222
+ end
223
+ end
224
+
186
225
  end
187
226
  end
@@ -25,5 +25,8 @@ module AASM
25
25
  attr_accessor :with_klass
26
26
 
27
27
  attr_accessor :enum
28
+
29
+ # namespace reader methods and constants
30
+ attr_accessor :namespace
28
31
  end
29
32
  end