aasm 4.12.0 → 4.12.1

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