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
@@ -8,6 +8,7 @@ module AASM::Core
8
8
  @name = name
9
9
  @state_machine = state_machine
10
10
  @transitions = []
11
+ @valid_transitions = {}
11
12
  @guards = Array(options[:guard] || options[:guards] || options[:if])
12
13
  @unless = Array(options[:unless]) #TODO: This could use a better name
13
14
 
@@ -62,6 +63,12 @@ module AASM::Core
62
63
  invoke_callbacks(@options[callback_name], record, args)
63
64
  end
64
65
 
66
+ def fire_transition_callbacks(obj, *args)
67
+ from_state = obj.aasm(state_machine.name).current_state
68
+ transition = @valid_transitions[from_state]
69
+ @valid_transitions[from_state].invoke_success_callbacks(obj, *args) if transition
70
+ end
71
+
65
72
  def ==(event)
66
73
  if event.is_a? Symbol
67
74
  name == event
@@ -103,7 +110,6 @@ module AASM::Core
103
110
  definitions
104
111
  end
105
112
 
106
- # Execute if test == false, otherwise return true/false depending on whether it would fire
107
113
  def _fire(obj, options={}, to_state=nil, *args)
108
114
  result = options[:test_only] ? false : nil
109
115
  if @transitions.map(&:from).any?
@@ -130,6 +136,7 @@ module AASM::Core
130
136
  if options[:test_only]
131
137
  # result = true
132
138
  else
139
+ Array(transition.to).each {|to| @valid_transitions[to] = transition }
133
140
  transition.execute(obj, *args)
134
141
  end
135
142
 
@@ -6,7 +6,7 @@ module AASM::Core
6
6
  alias_method :options, :opts
7
7
 
8
8
  def initialize(event, opts, &block)
9
- add_options_from_dsl(opts, [:on_transition, :guard, :after], &block) if block
9
+ add_options_from_dsl(opts, [:on_transition, :guard, :after, :success], &block) if block
10
10
 
11
11
  @event = event
12
12
  @from = opts[:from]
@@ -22,6 +22,9 @@ module AASM::Core
22
22
  @after = Array(opts[:after])
23
23
  @after = @after[0] if @after.size == 1
24
24
 
25
+ @success = Array(opts[:success])
26
+ @success = @success[0] if @success.size == 1
27
+
25
28
  @opts = opts
26
29
  end
27
30
 
@@ -43,6 +46,10 @@ module AASM::Core
43
46
  @from == value
44
47
  end
45
48
 
49
+ def invoke_success_callbacks(obj, *args)
50
+ _fire_callbacks(@success, obj, args)
51
+ end
52
+
46
53
  private
47
54
 
48
55
  def invoke_callbacks_compatible_with_guard(code, record, args, options={})
@@ -53,13 +60,13 @@ module AASM::Core
53
60
 
54
61
  case code
55
62
  when Symbol, String
56
- result = (record.__send__(:method, code.to_sym).arity == 0 ? record.__send__(code) : result = record.__send__(code, *args))
63
+ result = (record.__send__(:method, code.to_sym).arity == 0 ? record.__send__(code) : record.__send__(code, *args))
57
64
  failures << code unless result
58
65
  result
59
66
  when Proc
60
67
  if code.respond_to?(:parameters)
61
68
  # In Ruby's Proc, the 'arity' method is not a good condidate to know if
62
- # we should pass the arguments or not, since its does return 0 even in
69
+ # we should pass the arguments or not, since it does return 0 even in
63
70
  # presence of optional parameters.
64
71
  result = (code.parameters.size == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code))
65
72
 
@@ -85,7 +92,14 @@ module AASM::Core
85
92
  instance = code.new(record, *args)
86
93
  end
87
94
  result = instance.call
88
- failures << instance.method(:call).source_location.join('#') unless result
95
+
96
+ if Method.method_defined?(:source_location)
97
+ failures << instance.method(:call).source_location.join('#') unless result
98
+ else
99
+ # RubyMotion support ('source_location' not defined for Method)
100
+ failures << instance.method(:call) unless result
101
+ end
102
+
89
103
  result
90
104
  when Array
91
105
  if options[:guard]
@@ -103,5 +117,19 @@ module AASM::Core
103
117
  end
104
118
  end
105
119
 
120
+ def _fire_callbacks(code, record, args)
121
+ case code
122
+ when Symbol, String
123
+ arity = record.send(:method, code.to_sym).arity
124
+ record.send(code, *(arity < 0 ? args : args[0...arity]))
125
+ when Proc
126
+ code.arity == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
127
+ when Array
128
+ @success.map {|a| _fire_callbacks(a, obj, args)}
129
+ else
130
+ true
131
+ end
132
+ end
133
+
106
134
  end
107
135
  end # AASM
@@ -3,18 +3,18 @@ module AASM
3
3
  class UnknownStateMachineError < RuntimeError; end
4
4
 
5
5
  class InvalidTransition < RuntimeError
6
- attr_reader :object, :event_name, :state_machine_name, :failures
6
+ attr_reader :object, :event_name, :originating_state, :failures
7
7
 
8
8
  def initialize(object, event_name, state_machine_name, failures = [])
9
- @object, @event_name, @state_machine_name, @failures = object, event_name, state_machine_name, failures
9
+ @object, @event_name, @originating_state, @failures = object, event_name, object.aasm(state_machine_name).current_state, failures
10
10
  end
11
11
 
12
12
  def message
13
- "Event '#{event_name}' cannot transition from '#{object.aasm(state_machine_name).current_state}'. #{reasoning}"
13
+ "Event '#{event_name}' cannot transition from '#{originating_state}'. #{reasoning}"
14
14
  end
15
15
 
16
16
  def reasoning
17
- "Failed callback(s): #{@failures}." unless failures.empty?
17
+ "Failed callback(s): #{failures}." unless failures.empty?
18
18
  end
19
19
  end
20
20
 
@@ -7,15 +7,25 @@ module AASM
7
7
  hierarchy = base.ancestors.map {|klass| klass.to_s}
8
8
 
9
9
  if hierarchy.include?("ActiveRecord::Base")
10
+ require_persistence :active_record
10
11
  include_persistence base, :active_record
11
12
  elsif hierarchy.include?("Mongoid::Document")
13
+ require_persistence :mongoid
12
14
  include_persistence base, :mongoid
13
15
  elsif hierarchy.include?("MongoMapper::Document")
16
+ require_persistence :mongo_mapper
14
17
  include_persistence base, :mongo_mapper
15
18
  elsif hierarchy.include?("Sequel::Model")
19
+ require_persistence :sequel
16
20
  include_persistence base, :sequel
17
21
  elsif hierarchy.include?("Dynamoid::Document")
22
+ require_persistence :dynamoid
18
23
  include_persistence base, :dynamoid
24
+ elsif hierarchy.include?("Redis::Objects")
25
+ require_persistence :redis
26
+ include_persistence base, :redis
27
+ elsif hierarchy.include?("CDQManagedObject")
28
+ include_persistence base, :core_data_query
19
29
  else
20
30
  include_persistence base, :plain
21
31
  end
@@ -23,8 +33,11 @@ module AASM
23
33
 
24
34
  private
25
35
 
26
- def include_persistence(base, type)
36
+ def require_persistence(type)
27
37
  require File.join(File.dirname(__FILE__), 'persistence', "#{type}_persistence")
38
+ end
39
+
40
+ def include_persistence(base, type)
28
41
  base.send(:include, constantize("#{capitalize(type)}Persistence"))
29
42
  end
30
43
 
@@ -1,5 +1,3 @@
1
- require_relative 'base'
2
-
3
1
  module AASM
4
2
  module Persistence
5
3
  module ActiveRecordPersistence
@@ -31,15 +29,31 @@ module AASM
31
29
  def self.included(base)
32
30
  base.send(:include, AASM::Persistence::Base)
33
31
  base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
32
+ base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
34
33
 
35
- base.after_initialize do
36
- aasm_ensure_initial_state
37
- end
34
+ base.after_initialize :aasm_ensure_initial_state
38
35
 
39
36
  # ensure state is in the list of states
40
37
  base.validate :aasm_validate_states
41
38
  end
42
39
 
40
+ module ClassMethods
41
+ def aasm_create_scope(state_machine_name, scope_name)
42
+ conditions = {
43
+ table_name => { aasm(state_machine_name).attribute_name => scope_name.to_s }
44
+ }
45
+ if ActiveRecord::VERSION::MAJOR >= 3
46
+ class_eval do
47
+ scope scope_name, lambda { where(conditions) }
48
+ end
49
+ else
50
+ class_eval do
51
+ named_scope scope_name, :conditions => conditions
52
+ end
53
+ end
54
+ end
55
+ end
56
+
43
57
  module InstanceMethods
44
58
 
45
59
  # Writes <tt>state</tt> to the state column and persists it to the database
@@ -93,11 +107,11 @@ module AASM
93
107
  end
94
108
 
95
109
  def aasm_enum(name=:default)
96
- case AASM::StateMachine[self.class][name].config.enum
110
+ case AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
97
111
  when false then nil
98
112
  when true then aasm_guess_enum_method(name)
99
113
  when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
100
- else AASM::StateMachine[self.class][name].config.enum
114
+ else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
101
115
  end
102
116
  end
103
117
 
@@ -113,7 +127,7 @@ module AASM
113
127
  end
114
128
 
115
129
  def aasm_skipping_validations(state_machine_name)
116
- AASM::StateMachine[self.class][state_machine_name].config.skip_validation_on_save
130
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
117
131
  end
118
132
 
119
133
  def aasm_write_attribute(state, name=:default)
@@ -142,7 +156,7 @@ module AASM
142
156
  # foo.aasm_state # => nil
143
157
  #
144
158
  def aasm_ensure_initial_state
145
- AASM::StateMachine[self.class].keys.each do |state_machine_name|
159
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
146
160
  # checking via respond_to? does not work in Rails <= 3
147
161
  # if respond_to?(self.class.aasm(state_machine_name).attribute_name) && send(self.class.aasm(state_machine_name).attribute_name).blank? # Rails 4
148
162
  if aasm_column_is_blank?(state_machine_name)
@@ -189,18 +203,18 @@ module AASM
189
203
  end
190
204
 
191
205
  def requires_new?(state_machine_name)
192
- AASM::StateMachine[self.class][state_machine_name].config.requires_new_transaction
206
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_new_transaction
193
207
  end
194
208
 
195
209
  def requires_lock?(state_machine_name)
196
- AASM::StateMachine[self.class][state_machine_name].config.requires_lock
210
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_lock
197
211
  end
198
212
 
199
213
  def aasm_validate_states
200
- AASM::StateMachine[self.class].keys.each do |state_machine_name|
214
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
201
215
  unless aasm_skipping_validations(state_machine_name)
202
216
  if aasm_invalid_state?(state_machine_name)
203
- self.errors.add(AASM::StateMachine[self.class][state_machine_name].config.column , "is invalid")
217
+ self.errors.add(AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.column , "is invalid")
204
218
  end
205
219
  end
206
220
  end
@@ -63,53 +63,11 @@ module AASM
63
63
  private
64
64
 
65
65
  def create_scope?(name)
66
- @state_machine.config.create_scopes && !@klass.respond_to?(name)
66
+ @state_machine.config.create_scopes && !@klass.respond_to?(name) && @klass.respond_to?(:aasm_create_scope)
67
67
  end
68
68
 
69
69
  def create_scope(name)
70
- if ancestors_include?("ActiveRecord::Base")
71
- create_for_active_record(name)
72
- elsif ancestors_include?("Mongoid::Document")
73
- create_for_mongoid(name)
74
- elsif ancestors_include?("MongoMapper::Document")
75
- create_for_mongomapper(name)
76
- end
77
- end
78
-
79
- def ancestors_include?(class_name)
80
- @klass.ancestors.map { |klass| klass.to_s }.include?(class_name)
81
- end
82
-
83
- def create_for_active_record(name)
84
- conditions = {
85
- @klass.table_name => { @klass.aasm(@name).attribute_name => name.to_s }
86
- }
87
- if ActiveRecord::VERSION::MAJOR >= 3
88
- @klass.class_eval do
89
- scope name, lambda { where(conditions) }
90
- end
91
- else
92
- @klass.class_eval do
93
- named_scope name, :conditions => conditions
94
- end
95
- end
96
- end
97
-
98
- def create_for_mongoid(name)
99
- klass = @klass
100
- state_machine_name = @name
101
- scope_options = lambda {
102
- klass.send(
103
- :where,
104
- { klass.aasm(state_machine_name).attribute_name.to_sym => name.to_s }
105
- )
106
- }
107
- @klass.send(:scope, name, scope_options)
108
- end
109
-
110
- def create_for_mongomapper(name)
111
- conditions = { @klass.aasm(@name).attribute_name.to_sym => name.to_s }
112
- @klass.scope(name, lambda { @klass.where(conditions) })
70
+ @klass.aasm_create_scope(@name, name)
113
71
  end
114
72
  end # Base
115
73
 
@@ -0,0 +1,93 @@
1
+ module AASM
2
+ module Persistence
3
+ module CoreDataQueryPersistence
4
+ # This method:
5
+ #
6
+ # * extends the model with ClassMethods
7
+ # * includes InstanceMethods
8
+ #
9
+ # Adds
10
+ #
11
+ # after_initialize :aasm_ensure_initial_state
12
+ #
13
+
14
+ def self.included(base)
15
+ base.send(:include, AASM::Persistence::Base)
16
+ base.send(:include, AASM::Persistence::CoreDataQueryPersistence::InstanceMethods)
17
+ base.extend AASM::Persistence::CoreDataQueryPersistence::ClassMethods
18
+
19
+ base.after_initialize :aasm_ensure_initial_state
20
+ end
21
+
22
+ module ClassMethods
23
+ def aasm_create_scope(state_machine_name, scope_name)
24
+ scope(scope_name.to_sym, lambda { where(aasm(state_machine_name).attribute_name.to_sym).eq(scope_name.to_s) })
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+
30
+ # Writes <tt>state</tt> to the state column and persists it to the database
31
+ # using update_attribute (which bypasses validation)
32
+ #
33
+ # foo = Foo.find(1)
34
+ # foo.aasm.current_state # => :opened
35
+ # foo.close!
36
+ # foo.aasm.current_state # => :closed
37
+ # Foo.find(1).aasm.current_state # => :closed
38
+ #
39
+ # NOTE: intended to be called from an event
40
+ def aasm_write_state(state, name=:default)
41
+ raise "Cowardly refusing to save the current CoreDataQuery context"
42
+ aasm_write_state_without_persistence(state, name)
43
+ end
44
+
45
+ # Writes <tt>state</tt> to the state column, but does not persist it to the database
46
+ #
47
+ # foo = Foo.find(1)
48
+ # foo.aasm.current_state # => :opened
49
+ # foo.close
50
+ # foo.aasm.current_state # => :closed
51
+ # Foo.find(1).aasm.current_state # => :opened
52
+ # foo.save
53
+ # foo.aasm.current_state # => :closed
54
+ # Foo.find(1).aasm.current_state # => :closed
55
+ #
56
+ # NOTE: intended to be called from an event
57
+ def aasm_write_state_without_persistence(state, name=:default)
58
+ write_attribute(self.class.aasm(name).attribute_name, state.to_s)
59
+ end
60
+
61
+ private
62
+
63
+ # Ensures that if the aasm_state column is nil and the record is new
64
+ # that the initial state gets populated before validation on create
65
+ #
66
+ # foo = Foo.new
67
+ # foo.aasm_state # => nil
68
+ # foo.valid?
69
+ # foo.aasm_state # => "open" (where :open is the initial state)
70
+ #
71
+ #
72
+ # foo = Foo.find(:first)
73
+ # foo.aasm_state # => 1
74
+ # foo.aasm_state = nil
75
+ # foo.valid?
76
+ # foo.aasm_state # => nil
77
+ #
78
+ def aasm_ensure_initial_state
79
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
80
+ send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s) if send(self.class.aasm(state_machine_name).attribute_name).blank?
81
+ end
82
+ end
83
+ end # InstanceMethods
84
+
85
+ # module NamedScopeMethods
86
+ # def aasm_state_with_named_scope name, options = {}
87
+ # aasm_state_without_named_scope name, options
88
+ # self.named_scope name, :conditions => { "#{table_name}.#{self.aasm.attribute_name}" => name.to_s} unless self.respond_to?(name)
89
+ # end
90
+ # end
91
+ end
92
+ end # Persistence
93
+ end # AASM
@@ -1,5 +1,3 @@
1
- require_relative 'base'
2
-
3
1
  module AASM
4
2
  module Persistence
5
3
  module DynamoidPersistence
@@ -16,7 +14,7 @@ module AASM
16
14
  #
17
15
  base.class_eval %Q(
18
16
  def method_missing(method_name, *arguments, &block)
19
- if (AASM::StateMachine[self.class].keys.map { |state_machine_name| self.class.aasm(state_machine_name).attribute_name.to_s + "=" }).include? method_name.to_s
17
+ if (AASM::StateMachineStore.fetch(self.class, true).machine_names.map { |state_machine_name| self.class.aasm(state_machine_name).attribute_name.to_s + "=" }).include? method_name.to_s
20
18
  attribute_name = method_name.to_s.gsub("=", '')
21
19
  write_attribute(attribute_name.to_sym, *arguments)
22
20
  else
@@ -84,7 +82,7 @@ module AASM
84
82
  # foo.aasm_state # => nil
85
83
  #
86
84
  def aasm_ensure_initial_state
87
- AASM::StateMachine[self.class].keys.each do |state_machine_name|
85
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
88
86
  aasm(state_machine_name).enter_initial_state if send(self.class.aasm(state_machine_name).attribute_name).blank?
89
87
  end
90
88
  end
@@ -1,5 +1,3 @@
1
- require_relative 'base'
2
-
3
1
  module AASM
4
2
  module Persistence
5
3
  module MongoMapperPersistence
@@ -33,6 +31,7 @@ module AASM
33
31
  def self.included(base)
34
32
  base.send(:include, AASM::Persistence::Base)
35
33
  base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods)
34
+ base.extend AASM::Persistence::MongoMapperPersistence::ClassMethods
36
35
 
37
36
  base.before_create :aasm_ensure_initial_state
38
37
 
@@ -40,6 +39,13 @@ module AASM
40
39
  base.validate :aasm_validate_states
41
40
  end
42
41
 
42
+ module ClassMethods
43
+ def aasm_create_scope(state_machine_name, scope_name)
44
+ conditions = { aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s }
45
+ scope(scope_name, lambda { where(conditions) })
46
+ end
47
+ end
48
+
43
49
  module InstanceMethods
44
50
 
45
51
  # Writes <tt>state</tt> to the state column and persists it to the database
@@ -87,11 +93,11 @@ module AASM
87
93
 
88
94
  private
89
95
  def aasm_enum(name=:default)
90
- case AASM::StateMachine[self.class][name].config.enum
96
+ case AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
91
97
  when false then nil
92
98
  when true then aasm_guess_enum_method(name)
93
99
  when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
94
- else AASM::StateMachine[self.class][name].config.enum
100
+ else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
95
101
  end
96
102
  end
97
103
 
@@ -104,7 +110,7 @@ module AASM
104
110
  end
105
111
 
106
112
  def aasm_skipping_validations(state_machine_name)
107
- AASM::StateMachine[self.class][state_machine_name].config.skip_validation_on_save
113
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
108
114
  end
109
115
 
110
116
  def aasm_write_attribute(state, name=:default)
@@ -135,17 +141,17 @@ module AASM
135
141
  # foo.aasm_state # => nil
136
142
  #
137
143
  def aasm_ensure_initial_state
138
- AASM::StateMachine[self.class].keys.each do |state_machine_name|
144
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
139
145
  send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s) if send(self.class.aasm(state_machine_name).attribute_name).blank?
140
146
  end
141
147
  end
142
148
 
143
149
  def aasm_validate_states
144
- AASM::StateMachine[self.class].keys.each do |state_machine_name|
150
+ AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
145
151
  send("#{self.class.aasm(state_machine_name).attribute_name}=", aasm(state_machine_name).enter_initial_state.to_s) if send(self.class.aasm(state_machine_name).attribute_name).blank?
146
- unless AASM::StateMachine[self.class][state_machine_name].config.skip_validation_on_save
152
+ unless AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
147
153
  if aasm(state_machine_name).current_state && !aasm(state_machine_name).states.include?(aasm(state_machine_name).current_state)
148
- self.errors.add(AASM::StateMachine[self.class][state_machine_name].config.column , "is invalid")
154
+ self.errors.add(AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.column , "is invalid")
149
155
  end
150
156
  end
151
157
  end