aasm 4.12.0 → 4.12.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -1
  3. data/Appraisals +2 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +1 -1
  6. data/README.md +102 -8
  7. data/gemfiles/rails_4.2.gemfile +1 -0
  8. data/gemfiles/rails_5.0.gemfile +1 -0
  9. data/lib/aasm/base.rb +8 -0
  10. data/lib/aasm/core/event.rb +1 -1
  11. data/lib/aasm/core/transition.rb +1 -1
  12. data/lib/aasm/instance_base.rb +0 -2
  13. data/lib/aasm/minitest.rb +5 -0
  14. data/lib/aasm/minitest/allow_event.rb +13 -0
  15. data/lib/aasm/minitest/allow_transition_to.rb +13 -0
  16. data/lib/aasm/minitest/have_state.rb +13 -0
  17. data/lib/aasm/minitest/transition_from.rb +21 -0
  18. data/lib/aasm/minitest_spec.rb +15 -0
  19. data/lib/aasm/persistence/active_record_persistence.rb +25 -101
  20. data/lib/aasm/persistence/base.rb +7 -3
  21. data/lib/aasm/persistence/mongoid_persistence.rb +15 -60
  22. data/lib/aasm/persistence/orm.rb +142 -0
  23. data/lib/aasm/persistence/redis_persistence.rb +16 -11
  24. data/lib/aasm/persistence/sequel_persistence.rb +36 -63
  25. data/lib/aasm/version.rb +1 -1
  26. data/lib/generators/active_record/templates/migration.rb +1 -1
  27. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  28. data/lib/motion-aasm.rb +2 -0
  29. data/spec/models/active_record/complex_active_record_example.rb +5 -1
  30. data/spec/models/guardian_without_from_specified.rb +18 -0
  31. data/spec/models/namespaced_multiple_example.rb +14 -0
  32. data/spec/models/redis/complex_redis_example.rb +40 -0
  33. data/spec/models/redis/redis_multiple.rb +20 -0
  34. data/spec/models/redis/redis_simple.rb +20 -0
  35. data/spec/models/sequel/complex_sequel_example.rb +4 -3
  36. data/spec/models/sequel/invalid_persistor.rb +52 -0
  37. data/spec/models/sequel/sequel_multiple.rb +13 -13
  38. data/spec/models/sequel/sequel_simple.rb +13 -12
  39. data/spec/models/sequel/silent_persistor.rb +50 -0
  40. data/spec/models/sequel/transactor.rb +112 -0
  41. data/spec/models/sequel/validator.rb +93 -0
  42. data/spec/models/sequel/worker.rb +12 -0
  43. data/spec/spec_helpers/redis.rb +8 -0
  44. data/spec/unit/guard_spec.rb +17 -0
  45. data/spec/unit/guard_without_from_specified_spec.rb +10 -0
  46. data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
  47. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +4 -4
  48. data/spec/unit/persistence/active_record_persistence_spec.rb +4 -4
  49. data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
  50. data/spec/unit/persistence/redis_persistence_spec.rb +5 -25
  51. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +2 -2
  52. data/spec/unit/persistence/sequel_persistence_spec.rb +275 -2
  53. data/test/minitest_helper.rb +57 -0
  54. data/test/unit/minitest_matcher_test.rb +80 -0
  55. metadata +35 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fedd52d9c93d911e324c5c3594910d7fb7b33db2
4
- data.tar.gz: a0334890f17ce24960567a8f95e0cafd03375a9f
3
+ metadata.gz: 51fca1a6911cbe2585301606192b2d0a467ae7e7
4
+ data.tar.gz: c4bdfee904a029cec8329eb024c608f225a3b746
5
5
  SHA512:
6
- metadata.gz: 91bec3c1dfd3c450fb0565794026c0dcba137db1c42e5fb79a63544e4071c7ece69e36a2c42b9a5e45cf8790a1fca769c25ce6dc9f9050819a4c7dae7216bb5f
7
- data.tar.gz: 20e8f730c627d53ad7558240d808c2ac42e0540b57e0e78814e560668e80af18c0c83014eefb3d335356dd8bb58ff27425f412f0a8054921171e206cff6a88cf
6
+ metadata.gz: 7ce9707a179a75f5e75c038ae8102956503564bca475151a6c64dfad9862b313382fc6b7f3ddc2c8e928dfbb666667b171be5abc7bf7d569e5e72cd4ee59467e
7
+ data.tar.gz: e2c030b9c239c3ced525745ed32f192712ed946fff5f5ed45c8c2710fe3da2aa8291f41faf351b9241c1eb7e6ecf4bb4ad72aace93aeb6f91e0b8af58d253f73
@@ -22,10 +22,14 @@ gemfile:
22
22
 
23
23
  before_script:
24
24
  - mkdir /tmp/dynamodb
25
- - wget -O - http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.tar.gz | tar xz --directory /tmp/dynamodb
25
+ - wget -O - https://s3-ap-southeast-1.amazonaws.com/dynamodb-local-singapore/dynamodb_local_latest.tar.gz | tar xz --directory /tmp/dynamodb
26
26
  - java -Djava.library.path=/tmp/dynamodb/DynamoDBLocal_lib -jar /tmp/dynamodb/DynamoDBLocal.jar -inMemory -delayTransientStatuses -port 30180 &
27
27
  - mongod --version
28
28
 
29
+ script:
30
+ - bundle exec rspec spec
31
+ - bundle exec rake test
32
+
29
33
  matrix:
30
34
  exclude:
31
35
  - rvm: 1.9.3
data/Appraisals CHANGED
@@ -24,6 +24,7 @@ appraise 'rails_4.2' do
24
24
  gem 'sequel'
25
25
  gem 'dynamoid', '~> 1', :platforms => :ruby
26
26
  gem 'aws-sdk', '~>2', :platforms => :ruby
27
+ gem 'redis-objects'
27
28
  end
28
29
 
29
30
  appraise 'rails_4.2_mongoid_5' do
@@ -41,4 +42,5 @@ appraise 'rails_5.0' do
41
42
  # gem 'dynamoid', '~> 1', :platforms => :ruby
42
43
 
43
44
  gem 'aws-sdk', '~>2', :platforms => :ruby
45
+ gem 'redis-objects'
44
46
  end
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
+ ## 4.12.1
6
+
7
+ * DRY-up Mongoid and ActiveRecord Persistence, Add Sequel transactions and locking #475, thanks to [@Aryk] (https://github.com/Aryk)
8
+ * Add aliases for event methods #476, thanks to [@Aryk] (https://github.com/Aryk)
9
+ * Support Minitest spec expectations (#387), thanks to [@faragorn] (https://github.com/faragorn)
5
10
  ## 4.12.0
6
11
 
7
12
  * Fix thread safe issue with concurrent-ruby gem [see [pull-request #422](https://github.com/aasm/aasm/pull/442), thanks to [@reidmorrison](https://github.com/reidmorrison)
data/Gemfile CHANGED
@@ -4,4 +4,4 @@ gemspec
4
4
 
5
5
  gem 'sqlite3', :platforms => :ruby
6
6
  gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
7
- gem 'rails', '5.0.0'
7
+ gem 'rails', '5.0.2'
data/README.md CHANGED
@@ -210,6 +210,14 @@ Note that when passing arguments to a state transition, the first argument must
210
210
  In case of an error during the event processing the error is rescued and passed to `:error`
211
211
  callback, which can handle it or re-raise it for further propagation.
212
212
 
213
+ Also, you can define a method that will be called if any event fails:
214
+
215
+ ```
216
+ def aasm_event_failed(event_name, old_state_name)
217
+ # use custom exception/messages, report metrics, etc
218
+ end
219
+ ```
220
+
213
221
  During the transition's `:after` callback (and reliably only then, or in the global
214
222
  `after_all_transitions` callback) you can access the originating state (the from-state)
215
223
  and the target state (the to state), like this:
@@ -456,9 +464,6 @@ example.aasm(:work).current_state #=> :processing
456
464
  example.aasm(:question).current_state #=> :asked
457
465
  ```
458
466
 
459
- *Final note*: Support for multiple state machines per class is a pretty new feature
460
- (since version `4.3`), so please bear with us in case it doesn't work as expected.
461
-
462
467
  ### Auto-generated Status Constants
463
468
 
464
469
  AASM automatically [generates constants](https://github.com/aasm/aasm/pull/60)
@@ -715,8 +720,10 @@ end
715
720
 
716
721
  ### Redis
717
722
 
718
- AASM also supports persistence in Redis.
719
- Make sure to include Redis::Objects before you include AASM.
723
+ AASM also supports persistence in Redis via
724
+ [Redis::Objects](https://github.com/nateware/redis-objects).
725
+ Make sure to include Redis::Objects before you include AASM. Note that non-bang
726
+ events will work as bang events, persisting the changes on every call.
720
727
 
721
728
  ```ruby
722
729
  class User
@@ -896,6 +903,9 @@ class Job < ActiveRecord::Base
896
903
  ...
897
904
  end
898
905
 
906
+ aasm :another_state_machine, column: 'second_state' do
907
+ ...
908
+ end
899
909
  end
900
910
  ```
901
911
 
@@ -1006,8 +1016,6 @@ class Job
1006
1016
  end
1007
1017
  ```
1008
1018
 
1009
- Be aware though, that this is not yet released. It will be part of _AASM_ version `4.11.0`.
1010
-
1011
1019
  ### RubyMotion support
1012
1020
 
1013
1021
  Now supports [CodeDataQuery](https://github.com/infinitered/cdq.git) !
@@ -1022,7 +1030,9 @@ the 'instance method symbol / string' way whenever possible when defining guardi
1022
1030
 
1023
1031
  ### Testing
1024
1032
 
1025
- AASM provides some matchers for [RSpec](http://rspec.info): `transition_from`, `have_state`, `allow_event` and `allow_transition_to`. Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this
1033
+ #### RSpec
1034
+
1035
+ AASM provides some matchers for [RSpec](http://rspec.info): `transition_from`, `have_state`, `allow_event` and `allow_transition_to`. Add `require 'aasm/rspec'` to your `spec_helper.rb` file and use them like this:
1026
1036
 
1027
1037
  ```ruby
1028
1038
  # classes with only the default state machine
@@ -1058,6 +1068,90 @@ expect(multiple).to allow_transition_to(:processing).on(:move)
1058
1068
  expect(multiple).to_not allow_transition_to(:sleeping).on(:move)
1059
1069
  ```
1060
1070
 
1071
+ #### Minitest
1072
+
1073
+ AASM provides assertions and rspec-like expectations for [Minitest](https://github.com/seattlerb/minitest).
1074
+
1075
+ ##### Assertions
1076
+
1077
+ List of supported assertions: `assert_have_state`, `refute_have_state`, `assert_transitions_from`, `refute_transitions_from`, `assert_event_allowed`, `refute_event_allowed`, `assert_transition_to_allowed`, `refute_transition_to_allowed`.
1078
+
1079
+ Add `require 'aasm/minitest' to your `test_helper.rb` file and use them like this:
1080
+
1081
+ ```ruby
1082
+ # classes with only the default state machine
1083
+ job = Job.new
1084
+ assert_transitions_from job, :sleeping, to: :running, on_event: :run
1085
+ refute_transitions_from job, :sleeping, to: :cleaning, on_event: :run
1086
+ assert_have_state job, :sleeping
1087
+ refute_have_state job, :running
1088
+ assert_event_allowed job, :run
1089
+ refute_event_allowed job, :clean
1090
+ assert_transition_to_allowed job, :running
1091
+ refute_transition_to_allowed job, :cleaning
1092
+ # on_event also accept arguments
1093
+ assert_transitions_from job, :sleeping, :defragmentation, to: :running, on_event: :run
1094
+
1095
+ # classes with multiple state machine
1096
+ multiple = SimpleMultipleExample.new
1097
+ assert_transitions_from multiple, :standing, to: :walking, on_event: :walk, on: :move
1098
+ refute_transitions_from multiple, :standing, to: :running, on_event: :walk, on: :move
1099
+ assert_have_state multiple, :standing, on: :move
1100
+ refute_have_state multiple, :walking, on: :move
1101
+ assert_event_allowed multiple, :walk, on: :move
1102
+ refute_event_allowed multiple, :hold, on: :move
1103
+ assert_transition_to_allowed multiple, :walking, on: :move
1104
+ refute_transition_to_allowed multiple, :running, on: :move
1105
+ assert_transitions_from multiple, :sleeping, to: :processing, on_event: :start, on: :work
1106
+ refute_transitions_from multiple, :sleeping, to: :sleeping, on_event: :start, on: :work
1107
+ assert_have_state multiple, :sleeping, on: :work
1108
+ refute_have_state multiple, :processing, on: :work
1109
+ assert_event_allowed multiple, :start, on: :move
1110
+ refute_event_allowed multiple, :stop, on: :move
1111
+ assert_transition_to_allowed multiple, :processing, on: :move
1112
+ refute_transition_to_allowed multiple, :sleeping, on: :move
1113
+ ```
1114
+
1115
+ ##### Expectations
1116
+
1117
+ List of supported expectations: `must_transition_from`, `wont_transition_from`, `must_have_state`, `wont_have_state`, `must_allow_event`, `wont_allow_event`, `must_allow_transition_to`, `wont_allow_transition_to`.
1118
+
1119
+ Add `require 'aasm/minitest_spec'` to your `test_helper.rb` file and use them like this:
1120
+
1121
+ ```ruby
1122
+ # classes with only the default state machine
1123
+ job = Job.new
1124
+ job.must_transition_from :sleeping, to: :running, on_event: :run
1125
+ job.wont_transition_from :sleeping, to: :cleaning, on_event: :run
1126
+ job.must_have_state :sleeping
1127
+ job.wont_have_state :running
1128
+ job.must_allow_event :run
1129
+ job.wont_allow_event :clean
1130
+ job.must_allow_transition_to :running
1131
+ job.wont_allow_transition_to :cleaning
1132
+ # on_event also accept arguments
1133
+ job.must_transition_from :sleeping, :defragmentation, to: :running, on_event: :run
1134
+
1135
+ # classes with multiple state machine
1136
+ multiple = SimpleMultipleExample.new
1137
+ multiple.must_transition_from :standing, to: :walking, on_event: :walk, on: :move
1138
+ multiple.wont_transition_from :standing, to: :running, on_event: :walk, on: :move
1139
+ multiple.must_have_state :standing, on: :move
1140
+ multiple.wont_have_state :walking, on: :move
1141
+ multiple.must_allow_event :walk, on: :move
1142
+ multiple.wont_allow_event :hold, on: :move
1143
+ multiple.must_allow_transition_to :walking, on: :move
1144
+ multiple.wont_allow_transition_to :running, on: :move
1145
+ multiple.must_transition_from :sleeping, to: :processing, on_event: :start, on: :work
1146
+ multiple.wont_transition_from :sleeping, to: :sleeping, on_event: :start, on: :work
1147
+ multiple.must_have_state :sleeping, on: :work
1148
+ multiple.wont_have_state :processing, on: :work
1149
+ multiple.must_allow_event :start, on: :move
1150
+ multiple.wont_allow_event :stop, on: :move
1151
+ multiple.must_allow_transition_to :processing, on: :move
1152
+ multiple.wont_allow_transition_to :sleeping, on: :move
1153
+ ```
1154
+
1061
1155
  ## <a id="installation">Installation ##
1062
1156
 
1063
1157
  ### Manually from RubyGems.org ###
@@ -11,5 +11,6 @@ gem "mongoid", "~>4.0"
11
11
  gem "sequel"
12
12
  gem "dynamoid", "~> 1", :platforms => :ruby
13
13
  gem "aws-sdk", "~>2", :platforms => :ruby
14
+ gem "redis-objects"
14
15
 
15
16
  gemspec :path => "../"
@@ -8,5 +8,6 @@ gem "rails", "5.0.0"
8
8
  gem "mongoid", "~>6.0"
9
9
  gem "sequel"
10
10
  gem "aws-sdk", "~>2", :platforms => :ruby
11
+ gem "redis-objects"
11
12
 
12
13
  gemspec :path => "../"
@@ -130,6 +130,14 @@ module AASM
130
130
  aasm(aasm_name).current_event = event
131
131
  aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
132
132
  end
133
+
134
+ # Create aliases for the event methods. Keep the old names to maintain backwards compatibility.
135
+ if namespace?
136
+ klass.send(:alias_method, "may_#{name}_#{namespace}?", "may_#{name}?")
137
+ klass.send(:alias_method, "#{name}_#{namespace}!", "#{name}!")
138
+ klass.send(:alias_method, "#{name}_#{namespace}", name)
139
+ end
140
+
133
141
  end
134
142
 
135
143
  def after_all_transitions(*callbacks, &block)
@@ -96,7 +96,7 @@ module AASM::Core
96
96
  @transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
97
97
  end
98
98
  # Create a transition if :to is specified without :from (transitions from ANY state)
99
- if @transitions.empty? && definitions[:to]
99
+ if !definitions[:from] && definitions[:to]
100
100
  @transitions << AASM::Core::Transition.new(self, attach_event_guards(definitions), &block)
101
101
  end
102
102
  end
@@ -69,7 +69,7 @@ module AASM::Core
69
69
 
70
70
  case code
71
71
  when Symbol, String
72
- result = (record.__send__(:method, code.to_sym).arity == 0 ? record.__send__(code) : record.__send__(code, *args))
72
+ result = (record.__send__(:method, code.to_sym).arity != 0 ? record.__send__(code, *args) : record.__send__(code))
73
73
  failures << code unless result
74
74
  result
75
75
  when Proc
@@ -14,7 +14,6 @@ module AASM
14
14
 
15
15
  def current_state=(state)
16
16
  @instance.aasm_write_state_without_persistence(state, @name)
17
- # @current_state = state
18
17
  end
19
18
 
20
19
  def enter_initial_state
@@ -22,7 +21,6 @@ module AASM
22
21
  state_object = state_object_for_name(state_name)
23
22
 
24
23
  state_object.fire_callbacks(:before_enter, @instance)
25
- # state_object.fire_callbacks(:enter, @instance)
26
24
  self.current_state = state_name
27
25
  state_object.fire_callbacks(:after_enter, @instance)
28
26
 
@@ -0,0 +1,5 @@
1
+ Minitest = MiniTest unless defined? Minitest
2
+ # relative-require all minitest_spec files
3
+ Dir[File.dirname(__FILE__) + '/minitest/*.rb'].each do |file|
4
+ require 'aasm/minitest/' + File.basename(file, File.extname(file))
5
+ end
@@ -0,0 +1,13 @@
1
+ module Minitest::Assertions
2
+ def assert_event_allowed(object, event, options = {})
3
+ state_machine_name = options.fetch(:on, :default)
4
+ assert object.aasm(state_machine_name).may_fire_event?(event),
5
+ "Expected that the event :#{event} would be allowed (on :#{state_machine_name})"
6
+ end
7
+
8
+ def refute_event_allowed(object, event, options = {})
9
+ state_machine_name = options.fetch(:on, :default)
10
+ refute object.aasm(state_machine_name).may_fire_event?(event),
11
+ "Expected that the event :#{event} would not be allowed (on :#{state_machine_name})"
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Minitest::Assertions
2
+ def assert_transition_to_allowed(object, to_state, options = {})
3
+ state_machine_name = options.fetch(:on, :default)
4
+ assert object.aasm(state_machine_name).states(permitted: true).include?(to_state),
5
+ "Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
6
+ end
7
+
8
+ def refute_transition_to_allowed(object, to_state, options = {})
9
+ state_machine_name = options.fetch(:on, :default)
10
+ refute object.aasm(state_machine_name).states(permitted: true).include?(to_state),
11
+ "Expected that the state :#{to_state} would be reachable (on :#{state_machine_name})"
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Minitest::Assertions
2
+ def assert_have_state(object, state, options = {})
3
+ state_machine_name = options.fetch(:on, :default)
4
+ assert object.aasm(state_machine_name).current_state == state,
5
+ "Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
6
+ end
7
+
8
+ def refute_have_state(object, state, options = {})
9
+ state_machine_name = options.fetch(:on, :default)
10
+ refute object.aasm(state_machine_name).current_state == state,
11
+ "Expected that :#{object.aasm(state_machine_name).current_state} would be :#{state} (on :#{state_machine_name})"
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module Minitest::Assertions
2
+ def assert_transitions_from(object, from_state, *args)
3
+ options = args.first
4
+ options[:on] ||= :default
5
+ assert _transitions_from?(object, from_state, args, options),
6
+ "Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
7
+ end
8
+
9
+ def refute_transitions_from(object, from_state, *args)
10
+ options = args.first
11
+ options[:on] ||= :default
12
+ refute _transitions_from?(object, from_state, args, options),
13
+ "Expected transition state to :#{options[:to]} from :#{from_state} on event :#{options[:on_event]}, (on :#{options[:on]})"
14
+ end
15
+
16
+ def _transitions_from?(object, from_state, args, options)
17
+ state_machine_name = options[:on]
18
+ object.aasm(state_machine_name).current_state = from_state.to_sym
19
+ object.send(options[:on_event], *args) && options[:to].to_sym == object.aasm(state_machine_name).current_state
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'aasm/minitest'
2
+
3
+ module Minitest::Expectations
4
+ AASM.infect_an_assertion :assert_transitions_from, :must_transition_from, :do_not_flip
5
+ AASM.infect_an_assertion :refute_transitions_from, :wont_transition_from, :do_not_flip
6
+
7
+ AASM.infect_an_assertion :assert_transition_to_allowed, :must_allow_transition_to, :do_not_flip
8
+ AASM.infect_an_assertion :refute_transition_to_allowed, :wont_allow_transition_to, :do_not_flip
9
+
10
+ AASM.infect_an_assertion :assert_have_state, :must_have_state, :do_not_flip
11
+ AASM.infect_an_assertion :refute_have_state, :wont_have_state, :do_not_flip
12
+
13
+ AASM.infect_an_assertion :assert_event_allowed, :must_allow_event, :do_not_flip
14
+ AASM.infect_an_assertion :refute_event_allowed, :wont_allow_event, :do_not_flip
15
+ end
@@ -1,3 +1,4 @@
1
+ require 'aasm/persistence/orm'
1
2
  module AASM
2
3
  module Persistence
3
4
  module ActiveRecordPersistence
@@ -28,6 +29,7 @@ module AASM
28
29
  #
29
30
  def self.included(base)
30
31
  base.send(:include, AASM::Persistence::Base)
32
+ base.send(:include, AASM::Persistence::ORM)
31
33
  base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
32
34
  base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
33
35
 
@@ -56,67 +58,41 @@ module AASM
56
58
 
57
59
  module InstanceMethods
58
60
 
59
- # Writes <tt>state</tt> to the state column and persists it to the database
60
- #
61
- # foo = Foo.find(1)
62
- # foo.aasm.current_state # => :opened
63
- # foo.close!
64
- # foo.aasm.current_state # => :closed
65
- # Foo.find(1).aasm.current_state # => :closed
66
- #
67
- # NOTE: intended to be called from an event
68
- def aasm_write_state(state, name=:default)
69
- old_value = read_attribute(self.class.aasm(name).attribute_name)
70
- aasm_write_attribute state, name
71
-
72
- success = if aasm_skipping_validations(name)
73
- value = aasm_raw_attribute_value(state, name)
74
- aasm_update_column(name, value)
75
- else
76
- self.save
77
- end
61
+ private
78
62
 
79
- unless success
80
- aasm_rollback(name, old_value)
81
- raise ActiveRecord::RecordInvalid.new(self) if aasm_whiny_persistence(name)
82
- end
63
+ def aasm_raise_invalid_record
64
+ raise ActiveRecord::RecordInvalid.new(self)
65
+ end
83
66
 
84
- success
67
+ def aasm_save
68
+ self.save
85
69
  end
86
70
 
87
- # Writes <tt>state</tt> to the state column, but does not persist it to the database
88
- #
89
- # foo = Foo.find(1)
90
- # foo.aasm.current_state # => :opened
91
- # foo.close
92
- # foo.aasm.current_state # => :closed
93
- # Foo.find(1).aasm.current_state # => :opened
94
- # foo.save
95
- # foo.aasm.current_state # => :closed
96
- # Foo.find(1).aasm.current_state # => :closed
97
- #
98
- # NOTE: intended to be called from an event
99
- def aasm_write_state_without_persistence(state, name=:default)
100
- aasm_write_attribute(state, name)
71
+ def aasm_update_column(attribute_name, value)
72
+ self.class.unscoped.where(self.class.primary_key => self.id).update_all(attribute_name => value) == 1
101
73
  end
102
74
 
103
- private
75
+ def aasm_read_attribute(name)
76
+ read_attribute(name)
77
+ end
104
78
 
105
- def aasm_update_column(name, value)
106
- self.class.unscoped.where(self.class.primary_key => self.id).update_all(self.class.aasm(name).attribute_name => value) == 1
79
+ def aasm_write_attribute(name, value)
80
+ write_attribute(name, value)
107
81
  end
108
82
 
109
- def aasm_rollback(name, old_value)
110
- write_attribute(self.class.aasm(name).attribute_name, old_value)
111
- false
83
+ def aasm_transaction(requires_new, requires_lock)
84
+ self.class.transaction(:requires_new => requires_new) do
85
+ lock!(requires_lock) if requires_lock
86
+ yield
87
+ end
112
88
  end
113
89
 
114
90
  def aasm_enum(name=:default)
115
91
  case AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
116
- when false then nil
117
- when true then aasm_guess_enum_method(name)
118
- when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
119
- else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
92
+ when false then nil
93
+ when true then aasm_guess_enum_method(name)
94
+ when nil then aasm_guess_enum_method(name) if aasm_column_looks_like_enum(name)
95
+ else AASM::StateMachineStore.fetch(self.class, true).machine(name).config.enum
120
96
  end
121
97
  end
122
98
 
@@ -131,23 +107,11 @@ module AASM
131
107
  self.class.aasm(name).attribute_name.to_s.pluralize.to_sym
132
108
  end
133
109
 
134
- def aasm_skipping_validations(state_machine_name)
135
- AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
136
- end
137
-
138
- def aasm_whiny_persistence(state_machine_name)
139
- AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
140
- end
141
-
142
- def aasm_write_attribute(state, name=:default)
143
- write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
144
- end
145
-
146
110
  def aasm_raw_attribute_value(state, name=:default)
147
111
  if aasm_enum(name)
148
112
  self.class.send(aasm_enum(name))[state]
149
113
  else
150
- state.to_s
114
+ super
151
115
  end
152
116
  end
153
117
 
@@ -179,46 +143,6 @@ module AASM
179
143
  attribute_names.include?(attribute_name.to_s) && send(attribute_name).blank?
180
144
  end
181
145
 
182
- def aasm_fire_event(state_machine_name, name, options, *args, &block)
183
- event = self.class.aasm(state_machine_name).state_machine.events[name]
184
-
185
- if options[:persist]
186
- event.fire_callbacks(:before_transaction, self, *args)
187
- event.fire_global_callbacks(:before_all_transactions, self, *args)
188
- end
189
-
190
- begin
191
- success = if options[:persist]
192
- self.class.transaction(:requires_new => requires_new?(state_machine_name)) do
193
- lock!(requires_lock?(state_machine_name)) if requires_lock?(state_machine_name)
194
- super
195
- end
196
- else
197
- super
198
- end
199
-
200
- if options[:persist] && success
201
- event.fire_callbacks(:after_commit, self, *args)
202
- event.fire_global_callbacks(:after_all_commits, self, *args)
203
- end
204
- ensure
205
- if options[:persist]
206
- event.fire_callbacks(:after_transaction, self, *args)
207
- event.fire_global_callbacks(:after_all_transactions, self, *args)
208
- end
209
- end
210
-
211
- success
212
- end
213
-
214
- def requires_new?(state_machine_name)
215
- AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_new_transaction
216
- end
217
-
218
- def requires_lock?(state_machine_name)
219
- AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.requires_lock
220
- end
221
-
222
146
  def aasm_validate_states
223
147
  AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |state_machine_name|
224
148
  unless aasm_skipping_validations(state_machine_name)