aasm 4.9.0 → 4.10.0

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