aasm 4.11.0 → 4.12.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -17
  3. data/Appraisals +44 -0
  4. data/CHANGELOG.md +24 -1
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +4 -21
  7. data/README.md +81 -34
  8. data/Rakefile +6 -1
  9. data/TESTING.md +25 -0
  10. data/aasm.gemspec +5 -2
  11. data/gemfiles/rails_3.2.gemfile +13 -0
  12. data/gemfiles/rails_4.0.gemfile +8 -9
  13. data/gemfiles/rails_4.2.gemfile +9 -9
  14. data/gemfiles/rails_4.2_mongoid_5.gemfile +5 -9
  15. data/gemfiles/rails_5.0.gemfile +7 -16
  16. data/lib/aasm/aasm.rb +9 -3
  17. data/lib/aasm/base.rb +3 -1
  18. data/lib/aasm/configuration.rb +4 -0
  19. data/lib/aasm/core/event.rb +19 -9
  20. data/lib/aasm/core/state.rb +7 -0
  21. data/lib/aasm/core/transition.rb +9 -0
  22. data/lib/aasm/instance_base.rb +8 -8
  23. data/lib/aasm/persistence/active_record_persistence.rb +1 -1
  24. data/lib/aasm/persistence/base.rb +3 -3
  25. data/lib/aasm/persistence/mongoid_persistence.rb +48 -9
  26. data/lib/aasm/persistence.rb +0 -3
  27. data/lib/aasm/state_machine.rb +4 -2
  28. data/lib/aasm/state_machine_store.rb +5 -2
  29. data/lib/aasm/version.rb +1 -1
  30. data/lib/generators/active_record/aasm_generator.rb +1 -1
  31. data/lib/motion-aasm.rb +0 -1
  32. data/spec/en.yml +3 -0
  33. data/spec/generators/active_record_generator_spec.rb +42 -34
  34. data/spec/generators/mongoid_generator_spec.rb +4 -6
  35. data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
  36. data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
  37. data/spec/models/active_record/simple_new_dsl.rb +2 -2
  38. data/spec/models/{transactor.rb → active_record/transactor.rb} +0 -2
  39. data/spec/models/{validator.rb → active_record/validator.rb} +6 -3
  40. data/spec/models/callbacks/basic.rb +5 -2
  41. data/spec/models/guard_with_params.rb +24 -0
  42. data/spec/models/guard_with_params_multiple.rb +18 -0
  43. data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
  44. data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
  45. data/spec/models/mongoid/simple_mongoid.rb +2 -2
  46. data/spec/models/mongoid/validator_mongoid.rb +100 -0
  47. data/spec/models/multi_transitioner.rb +10 -0
  48. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
  49. data/spec/models/parametrised_event.rb +7 -0
  50. data/spec/models/simple_multiple_example.rb +12 -0
  51. data/spec/models/sub_class.rb +34 -0
  52. data/spec/spec_helper.rb +0 -33
  53. data/spec/spec_helpers/active_record.rb +7 -0
  54. data/spec/spec_helpers/dynamoid.rb +33 -0
  55. data/spec/spec_helpers/mongoid.rb +7 -0
  56. data/spec/spec_helpers/redis.rb +7 -0
  57. data/spec/spec_helpers/remove_warnings.rb +1 -0
  58. data/spec/spec_helpers/sequel.rb +7 -0
  59. data/spec/unit/api_spec.rb +76 -73
  60. data/spec/unit/callbacks_spec.rb +5 -0
  61. data/spec/unit/event_spec.rb +12 -0
  62. data/spec/unit/guard_with_params_multiple_spec.rb +10 -0
  63. data/spec/unit/guard_with_params_spec.rb +14 -0
  64. data/spec/unit/inspection_spec.rb +5 -0
  65. data/spec/unit/localizer_spec.rb +55 -53
  66. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
  67. data/spec/unit/override_warning_spec.rb +8 -0
  68. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +452 -445
  69. data/spec/unit/persistence/active_record_persistence_spec.rb +523 -490
  70. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
  71. data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
  72. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +87 -10
  73. data/spec/unit/persistence/mongoid_persistence_spec.rb +89 -10
  74. data/spec/unit/persistence/redis_persistence_spec.rb +3 -7
  75. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +4 -9
  76. data/spec/unit/persistence/sequel_persistence_spec.rb +4 -9
  77. data/spec/unit/simple_multiple_example_spec.rb +28 -0
  78. data/spec/unit/subclassing_multiple_spec.rb +37 -2
  79. data/spec/unit/subclassing_spec.rb +17 -2
  80. metadata +77 -32
  81. data/gemfiles/rails_3.2_stable.gemfile +0 -15
  82. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -17
  83. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -18
  84. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
  85. data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
  86. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  87. data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
  88. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  89. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -146
  90. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
  91. /data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
@@ -34,5 +34,9 @@ module AASM
34
34
 
35
35
  # Configure a logger, with default being a Logger to STDERR
36
36
  attr_accessor :logger
37
+
38
+ class << self
39
+ attr_accessor :hide_warnings
40
+ end
37
41
  end
38
42
  end
@@ -22,10 +22,21 @@ module AASM::Core
22
22
  :before_transaction,
23
23
  :ensure,
24
24
  :error,
25
+ :before_success,
25
26
  :success,
26
27
  ], &block) if block
27
28
  end
28
29
 
30
+ # called internally by Ruby 1.9 after clone()
31
+ def initialize_copy(orig)
32
+ super
33
+ @transitions = @transitions.collect { |transition| transition.clone }
34
+ @guards = @guards.dup
35
+ @unless = @unless.dup
36
+ @options = {}
37
+ orig.options.each_pair { |name, setting| @options[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
38
+ end
39
+
29
40
  # a neutered version of fire - it doesn't actually fire the event, it just
30
41
  # executes the transition guards to determine if a transition is even
31
42
  # an option given current conditions.
@@ -112,12 +123,8 @@ module AASM::Core
112
123
 
113
124
  def _fire(obj, options={}, to_state=nil, *args)
114
125
  result = options[:test_only] ? false : nil
115
- if @transitions.map(&:from).any?
116
- transitions = @transitions.select { |t| t.from == obj.aasm(state_machine.name).current_state }
117
- return result if transitions.size == 0
118
- else
119
- transitions = @transitions
120
- end
126
+ transitions = @transitions.select { |t| t.from == obj.aasm(state_machine.name).current_state || t.from == nil}
127
+ return result if transitions.size == 0
121
128
 
122
129
  # If to_state is not nil it either contains a potential
123
130
  # to_state or an arg
@@ -126,16 +133,19 @@ module AASM::Core
126
133
  args.unshift(to_state)
127
134
  to_state = nil
128
135
  end
136
+ else
137
+ args.unshift(nil) if args.nil? || args.empty? # If single arg given which is nil, push it back to args
129
138
  end
130
139
 
131
140
  transitions.each do |transition|
132
141
  next if to_state and !Array(transition.to).include?(to_state)
133
- if (options.key?(:may_fire) && Array(transition.to).include?(options[:may_fire])) ||
142
+ if (options.key?(:may_fire) && transition.eql?(options[:may_fire])) ||
134
143
  (!options.key?(:may_fire) && transition.allowed?(obj, *args))
135
- result = to_state || Array(transition.to).first
144
+
136
145
  if options[:test_only]
137
- # result = true
146
+ result = transition
138
147
  else
148
+ result = to_state || Array(transition.to).first
139
149
  Array(transition.to).each {|to| @valid_transitions[to] = transition }
140
150
  transition.execute(obj, *args)
141
151
  end
@@ -9,6 +9,13 @@ module AASM::Core
9
9
  update(options)
10
10
  end
11
11
 
12
+ # called internally by Ruby 1.9 after clone()
13
+ def initialize_copy(orig)
14
+ super
15
+ @options = {}
16
+ orig.options.each_pair { |name, setting| @options[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
17
+ end
18
+
12
19
  def ==(state)
13
20
  if state.is_a? Symbol
14
21
  name == state
@@ -28,6 +28,15 @@ module AASM::Core
28
28
  @opts = opts
29
29
  end
30
30
 
31
+ # called internally by Ruby 1.9 after clone()
32
+ def initialize_copy(orig)
33
+ super
34
+ @guards = @guards.dup
35
+ @unless = @unless.dup
36
+ @opts = {}
37
+ orig.opts.each_pair { |name, setting| @opts[name] = setting.is_a?(Hash) || setting.is_a?(Array) ? setting.dup : setting }
38
+ end
39
+
31
40
  def allowed?(obj, *args)
32
41
  invoke_callbacks_compatible_with_guard(@guards, obj, args, :guard => true) &&
33
42
  invoke_callbacks_compatible_with_guard(@unless, obj, args, :unless => true)
@@ -33,9 +33,9 @@ module AASM
33
33
  AASM::Localizer.new.human_state_name(@instance.class, state_object_for_name(current_state))
34
34
  end
35
35
 
36
- def states(options={})
36
+ def states(options={}, *args)
37
37
  if options.has_key?(:permitted)
38
- selected_events = events(:permitted => options[:permitted])
38
+ selected_events = events({:permitted => options[:permitted]}, *args)
39
39
  # An array of arrays. Each inner array represents the transitions that
40
40
  # transition from the current state for an event
41
41
  event_transitions = selected_events.map {|e| e.transitions_from_state(current_state) }
@@ -45,10 +45,10 @@ module AASM
45
45
  return nil if transitions.empty?
46
46
 
47
47
  # Return the :to state of the first transition that is allowed (or not) or nil
48
- if options[:permitted]
49
- transition = transitions.find { |t| t.allowed?(@instance) }
48
+ if options[:permitted]
49
+ transition = transitions.find { |t| t.allowed?(@instance, *args) }
50
50
  else
51
- transition = transitions.find { |t| !t.allowed?(@instance) }
51
+ transition = transitions.find { |t| !t.allowed?(@instance, *args) }
52
52
  end
53
53
  transition ? transition.to : nil
54
54
  end.flatten.compact.uniq
@@ -60,7 +60,7 @@ module AASM
60
60
  end
61
61
  end
62
62
 
63
- def events(options={})
63
+ def events(options={}, *args)
64
64
  state = options[:state] || current_state
65
65
  events = @instance.class.aasm(@name).events.select {|e| e.transitions_from_state?(state) }
66
66
 
@@ -71,9 +71,9 @@ module AASM
71
71
  # filters the results of events_for_current_state so that only those that
72
72
  # are really currently possible (given transition guards) are shown.
73
73
  if options[:permitted]
74
- events.select! { |e| @instance.send("may_#{e.name}?") }
74
+ events.select! { |e| @instance.send("may_#{e.name}?", *args) }
75
75
  else
76
- events.select! { |e| !@instance.send("may_#{e.name}?") }
76
+ events.select! { |e| !@instance.send("may_#{e.name}?", *args) }
77
77
  end
78
78
  end
79
79
 
@@ -103,7 +103,7 @@ module AASM
103
103
  private
104
104
 
105
105
  def aasm_update_column(name, value)
106
- self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
106
+ self.class.unscoped.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
107
107
  end
108
108
 
109
109
  def aasm_rollback(name, old_value)
@@ -53,9 +53,9 @@ module AASM
53
53
 
54
54
  class Base
55
55
  # make sure to create a (named) scope for each state
56
- def state_with_scope(name, *args)
57
- state_without_scope(name, *args)
58
- create_scope(name) if create_scope?(name)
56
+ def state_with_scope(*args)
57
+ names = state_without_scope(*args)
58
+ names.each { |name| create_scope(name) if create_scope?(name) }
59
59
  end
60
60
  alias_method :state_without_scope, :state
61
61
  alias_method :state, :state_with_scope
@@ -50,8 +50,7 @@ module AASM
50
50
 
51
51
  module InstanceMethods
52
52
 
53
- # Writes <tt>state</tt> to the state column and persists it to the database
54
- # using update_attribute (which bypasses validation)
53
+ # Writes <tt>state</tt> to the state field and persists it to the database
55
54
  #
56
55
  # foo = Foo.find(1)
57
56
  # foo.aasm.current_state # => :opened
@@ -62,17 +61,24 @@ module AASM
62
61
  # NOTE: intended to be called from an event
63
62
  def aasm_write_state(state, name=:default)
64
63
  old_value = read_attribute(self.class.aasm(name).attribute_name)
65
- write_attribute(self.class.aasm(name).attribute_name, state.to_s)
64
+ aasm_write_attribute(state, name)
66
65
 
67
- unless self.save(:validate => false)
68
- write_attribute(self.class.aasm(name).attribute_name, old_value)
69
- return false
66
+ success = if aasm_skipping_validations(name)
67
+ value = aasm_raw_attribute_value(state, name)
68
+ aasm_update_column(name, value)
69
+ else
70
+ self.save
71
+ end
72
+
73
+ unless success
74
+ aasm_rollback(name, old_value)
75
+ raise Mongoid::Errors::Validations.new(self) if aasm_whiny_persistence(name)
70
76
  end
71
77
 
72
- true
78
+ success
73
79
  end
74
80
 
75
- # Writes <tt>state</tt> to the state column, but does not persist it to the database
81
+ # Writes <tt>state</tt> to the state field, but does not persist it to the database
76
82
  #
77
83
  # foo = Foo.find(1)
78
84
  # foo.aasm.current_state # => :opened
@@ -85,11 +91,44 @@ module AASM
85
91
  #
86
92
  # NOTE: intended to be called from an event
87
93
  def aasm_write_state_without_persistence(state, name=:default)
88
- write_attribute(self.class.aasm(name).attribute_name, state.to_s)
94
+ aasm_write_attribute(state, name)
89
95
  end
90
96
 
91
97
  private
92
98
 
99
+ def aasm_update_column(name, value)
100
+ attribute_name = self.class.aasm(name).attribute_name
101
+
102
+ if Mongoid::VERSION.to_f >= 4
103
+ set(Hash[attribute_name, value])
104
+ else
105
+ set(attribute_name, value)
106
+ end
107
+
108
+ true
109
+ end
110
+
111
+ def aasm_rollback(name, old_value)
112
+ write_attribute(self.class.aasm(name).attribute_name, old_value)
113
+ false
114
+ end
115
+
116
+ def aasm_skipping_validations(state_machine_name)
117
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
118
+ end
119
+
120
+ def aasm_whiny_persistence(state_machine_name)
121
+ AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
122
+ end
123
+
124
+ def aasm_write_attribute(state, name=:default)
125
+ write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
126
+ end
127
+
128
+ def aasm_raw_attribute_value(state, _name=:default)
129
+ state.to_s
130
+ end
131
+
93
132
  # Ensures that if the aasm_state column is nil and the record is new
94
133
  # that the initial state gets populated before validation on create
95
134
  #
@@ -12,9 +12,6 @@ module AASM
12
12
  elsif hierarchy.include?("Mongoid::Document")
13
13
  require_persistence :mongoid
14
14
  include_persistence base, :mongoid
15
- elsif hierarchy.include?("MongoMapper::Document")
16
- require_persistence :mongo_mapper
17
- include_persistence base, :mongo_mapper
18
15
  elsif hierarchy.include?("Sequel::Model")
19
16
  require_persistence :sequel
20
17
  include_persistence base, :sequel
@@ -16,8 +16,10 @@ module AASM
16
16
  # called internally by Ruby 1.9 after clone()
17
17
  def initialize_copy(orig)
18
18
  super
19
- @states = @states.dup
20
- @events = @events.dup
19
+ @states = orig.states.collect { |state| state.clone }
20
+ @events = {}
21
+ orig.events.each_pair { |name, event| @events[name] = event.clone }
22
+ @global_callbacks = @global_callbacks.dup
21
23
  end
22
24
 
23
25
  def add_state(state_name, klass, options)
@@ -1,8 +1,11 @@
1
+ require 'concurrent'
1
2
  module AASM
2
3
  class StateMachineStore
4
+ @stores = Concurrent::Map.new
5
+
3
6
  class << self
4
7
  def stores
5
- @stores ||= {}
8
+ @stores
6
9
  end
7
10
 
8
11
  # do not overwrite existing state machines, which could have been created by
@@ -38,7 +41,7 @@ module AASM
38
41
  end
39
42
 
40
43
  def initialize
41
- @machines = {}
44
+ @machines = Concurrent::Map.new
42
45
  end
43
46
 
44
47
  def clone
data/lib/aasm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "4.11.0"
2
+ VERSION = "4.12.0"
3
3
  end
@@ -12,7 +12,7 @@ module ActiveRecord
12
12
 
13
13
  def copy_aasm_migration
14
14
  if model_exists?
15
- migration_template "migration_existing.rb", "db/migrate/add_aasm_state_to_#{table_name}.rb"
15
+ migration_template "migration_existing.rb", "db/migrate/add_#{column_name}_to_#{table_name}.rb"
16
16
  else
17
17
  migration_template "migration.rb", "db/migrate/aasm_create_#{table_name}.rb"
18
18
  end
data/lib/motion-aasm.rb CHANGED
@@ -13,7 +13,6 @@ exclude_files = [
13
13
  'aasm/rspec.*',
14
14
  'aasm/persistence/active_record_persistence.rb',
15
15
  'aasm/persistence/dynamoid_persistence.rb',
16
- 'aasm/persistence/mongo_mapper_persistence.rb',
17
16
  'aasm/persistence/mongoid_persistence.rb',
18
17
  'aasm/persistence/sequel_persistence.rb',
19
18
  'aasm/persistence/redis_persistence.rb'
data/spec/en.yml CHANGED
@@ -7,3 +7,6 @@ en:
7
7
  attributes:
8
8
  localizer_test_model:
9
9
  aasm_state/opened: "It's open now!"
10
+ errors:
11
+ messages:
12
+ record_invalid: "Invalid record"
@@ -1,39 +1,47 @@
1
1
  require 'spec_helper'
2
- require 'generator_spec'
3
- require 'generators/active_record/aasm_generator'
4
2
 
5
- describe ActiveRecord::Generators::AASMGenerator, type: :generator do
6
- destination File.expand_path("../../../tmp", __FILE__)
3
+ if defined?(ActiveRecord)
4
+ require 'generator_spec'
5
+ require 'generators/active_record/aasm_generator'
6
+
7
+ describe ActiveRecord::Generators::AASMGenerator, type: :generator do
8
+ destination File.expand_path("../../../tmp", __FILE__)
9
+
10
+ before(:all) do
11
+ prepare_destination
12
+ end
13
+
14
+ it "creates model with aasm block for default column_name" do
15
+ run_generator %w(user)
16
+ assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
17
+ end
18
+
19
+ it "creates model with aasm block for custom column_name" do
20
+ run_generator %w(user state)
21
+ assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
22
+ end
23
+
24
+ it "creates model with aasm block for namespaced model" do
25
+ run_generator %w(Admin::User state)
26
+ assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
27
+ end
28
+
29
+ it "creates migration for model with aasm_column" do
30
+ run_generator %w(post)
31
+ assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/
32
+ end
33
+
34
+ it "add aasm_column in existing model" do
35
+ run_generator %w(job)
36
+ assert_file "app/models/job.rb"
37
+ run_generator %w(job)
38
+ assert_migration "db/migrate/add_aasm_state_to_jobs.rb"
39
+ end
40
+
41
+ it "add custom aasm_column in existing model" do
42
+ run_generator %w(job state)
43
+ assert_migration "db/migrate/add_state_to_jobs.rb"
44
+ end
7
45
 
8
- before(:all) do
9
- prepare_destination
10
46
  end
11
-
12
- it "creates model with aasm block for default column_name" do
13
- run_generator %w(user)
14
- assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/
15
- end
16
-
17
- it "creates model with aasm block for custom column_name" do
18
- run_generator %w(user state)
19
- assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/
20
- end
21
-
22
- it "creates model with aasm block for namespaced model" do
23
- run_generator %w(Admin::User state)
24
- assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/
25
- end
26
-
27
- it "creates migration for model with aasm_column" do
28
- run_generator %w(post)
29
- assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/
30
- end
31
-
32
- it "add aasm_column in existing model" do
33
- run_generator %w(job)
34
- assert_file "app/models/job.rb"
35
- run_generator %w(job)
36
- assert_migration "db/migrate/add_aasm_state_to_jobs.rb"
37
- end
38
-
39
47
  end
@@ -1,9 +1,8 @@
1
1
  require 'spec_helper'
2
- require 'generator_spec'
3
- require 'generators/mongoid/aasm_generator'
4
2
 
5
- begin
6
- require "mongoid"
3
+ if defined?(Mongoid::Document)
4
+ require 'generator_spec'
5
+ require 'generators/mongoid/aasm_generator'
7
6
 
8
7
  describe Mongoid::Generators::AASMGenerator, type: :generator do
9
8
  destination File.expand_path("../../../tmp", __FILE__)
@@ -28,6 +27,5 @@ begin
28
27
  end
29
28
 
30
29
  end
31
- rescue LoadError
32
- puts "Not running Mongoid specs because mongoid gem is not installed!!!"
30
+
33
31
  end
@@ -1,5 +1,3 @@
1
- require 'active_record'
2
-
3
1
  class InvalidPersistor < ActiveRecord::Base
4
2
  include AASM
5
3
  aasm :column => :status, :skip_validation_on_save => true do
@@ -1,5 +1,3 @@
1
- require 'active_record'
2
-
3
1
  class SilentPersistor < ActiveRecord::Base
4
2
  include AASM
5
3
  aasm :column => :status, :whiny_persistence => false do
@@ -2,7 +2,7 @@ class SimpleNewDsl < ActiveRecord::Base
2
2
  include AASM
3
3
  aasm :column => :status
4
4
  aasm do
5
- state :unknown_scope
5
+ state :unknown_scope, :another_unknown_scope
6
6
  state :new
7
7
  end
8
8
  end
@@ -11,7 +11,7 @@ class MultipleSimpleNewDsl < ActiveRecord::Base
11
11
  include AASM
12
12
  aasm :left, :column => :status
13
13
  aasm :left do
14
- state :unknown_scope
14
+ state :unknown_scope, :another_unknown_scope
15
15
  state :new
16
16
  end
17
17
  end
@@ -1,5 +1,3 @@
1
- require 'active_record'
2
-
3
1
  class Transactor < ActiveRecord::Base
4
2
 
5
3
  belongs_to :worker
@@ -1,12 +1,15 @@
1
- require 'active_record'
2
-
3
1
  class Validator < ActiveRecord::Base
4
2
  attr_accessor :after_all_transactions_performed,
5
3
  :after_transaction_performed_on_fail,
6
4
  :after_transaction_performed_on_run,
7
5
  :before_all_transactions_performed,
8
6
  :before_transaction_performed_on_fail,
9
- :before_transaction_performed_on_run
7
+ :before_transaction_performed_on_run,
8
+ :invalid
9
+
10
+ validate do |model|
11
+ errors.add(:validator, "invalid") if invalid
12
+ end
10
13
 
11
14
  include AASM
12
15
 
@@ -43,6 +43,7 @@ module Callbacks
43
43
  :before => :before_event,
44
44
  :after => :after_event,
45
45
  :guard => :event_guard,
46
+ :before_success => :event_before_success,
46
47
  :ensure => :ensure_event do
47
48
  transitions :to => :closed, :from => [:open],
48
49
  :guard => :transition_guard,
@@ -78,6 +79,8 @@ module Callbacks
78
79
  def event_guard; log('event_guard'); !@fail_event_guard; end
79
80
  def transition_guard; log('transition_guard'); !@fail_transition_guard; end
80
81
 
82
+ def event_before_success; log('event_before_success'); end
83
+
81
84
  def after_transition; log('after_transition'); end
82
85
  def after_all_transitions; log('after_all_transitions'); end
83
86
 
@@ -86,8 +89,8 @@ module Callbacks
86
89
  def after_event; log('after_event'); end
87
90
  def after_all_events; log('after_all_events'); end
88
91
 
89
- def after_transition; log('after_transition'); end
90
- def success_transition; log('transition_success'); end
92
+ def after_transition; log('after_transition'); end
93
+ def success_transition; log('transition_success'); end
91
94
 
92
95
  def ensure_event; log('ensure'); end
93
96
  def ensure_on_all_events; log('ensure'); end
@@ -0,0 +1,24 @@
1
+ class GuardWithParams
2
+ include AASM
3
+ aasm do
4
+ state :new, :reviewed, :finalized
5
+
6
+ event :mark_as_reviewed do
7
+ transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
8
+ end
9
+ end
10
+
11
+ def user_is_manager?(user)
12
+ ok = false
13
+ if user && user.has_role?(:manager)
14
+ ok = true
15
+ end
16
+ return ok
17
+ end
18
+ end
19
+
20
+ class GuardParamsClass
21
+ def has_role?(role)
22
+ true
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ class GuardWithParamsMultiple
2
+ include AASM
3
+ aasm(:left) do
4
+ state :new, :reviewed, :finalized
5
+
6
+ event :mark_as_reviewed do
7
+ transitions :from => :new, :to => :reviewed, :guards => [:user_is_manager?]
8
+ end
9
+ end
10
+
11
+ def user_is_manager?(user)
12
+ ok = false
13
+ if user.has_role? :manager
14
+ ok = true
15
+ end
16
+ return ok
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ class InvalidPersistorMongoid
2
+ include Mongoid::Document
3
+ include AASM
4
+
5
+ field :name
6
+ field :status
7
+
8
+ aasm :left, column: :status, skip_validation_on_save: true do
9
+ state :sleeping, :initial => true
10
+ state :running
11
+ event :run do
12
+ transitions :to => :running, :from => :sleeping
13
+ end
14
+ event :sleep do
15
+ transitions :to => :sleeping, :from => :running
16
+ end
17
+ end
18
+ validates_presence_of :name
19
+ end
20
+
21
+ class MultipleInvalidPersistorMongoid
22
+ include Mongoid::Document
23
+ include AASM
24
+
25
+ field :name
26
+ field :status
27
+
28
+ aasm :left, column: :status, skip_validation_on_save: true do
29
+ state :sleeping, :initial => true
30
+ state :running
31
+ event :run do
32
+ transitions :to => :running, :from => :sleeping
33
+ end
34
+ event :sleep do
35
+ transitions :to => :sleeping, :from => :running
36
+ end
37
+ end
38
+ validates_presence_of :name
39
+ end
@@ -0,0 +1,39 @@
1
+ class SilentPersistorMongoid
2
+ include Mongoid::Document
3
+ include AASM
4
+
5
+ field :name
6
+ field :status
7
+
8
+ aasm :left, column: :status, whiny_persistence: false do
9
+ state :sleeping, :initial => true
10
+ state :running
11
+ event :run do
12
+ transitions :to => :running, :from => :sleeping
13
+ end
14
+ event :sleep do
15
+ transitions :to => :sleeping, :from => :running
16
+ end
17
+ end
18
+ validates_presence_of :name
19
+ end
20
+
21
+ class MultipleSilentPersistorMongoid
22
+ include Mongoid::Document
23
+ include AASM
24
+
25
+ field :name
26
+ field :status
27
+
28
+ aasm :left, column: :status, whiny_persistence: false do
29
+ state :sleeping, :initial => true
30
+ state :running
31
+ event :run do
32
+ transitions :to => :running, :from => :sleeping
33
+ end
34
+ event :sleep do
35
+ transitions :to => :sleeping, :from => :running
36
+ end
37
+ end
38
+ validates_presence_of :name
39
+ end