aasm 4.0.3 → 4.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d198d23fad17dc052b4135e5ef02470edd8e146
4
- data.tar.gz: 85019079c1b7cfb236cf529b833561ba35030d51
3
+ metadata.gz: 4f80e2467a731eee5737b3c74cfb3d4236be0df5
4
+ data.tar.gz: 7175348561bd968b2208bb1a54b382dc4d72d2e8
5
5
  SHA512:
6
- metadata.gz: c1a3a8f5df97b012148fa50b79150d218f0dad130a4014e68502a2982b98ab3a6b79148832dac285321901366ab5ec976af11a5f431966ac528d60d5c62dcc5c
7
- data.tar.gz: 9e09e2ec97235c8761fd34a4c884cb6d9579e9960acf02815f472e0068586b8c4d2ff50b6d08d71f6571f31d81aa9cf345b94784d7cde1a066b1ddf0f44c466b
6
+ metadata.gz: 4b435f505dc2a2f30302ac902fa1264d70f8c40f5d4101ac669dc8bac1ddddc34c9b67aca1ea5c899074814a3ef8fdb272c008ed10480c156bdaacd5adcb4a77
7
+ data.tar.gz: 50ac955db2fda8ca2bf711f0e2dcabf648996c021bb3921ace2793cef1ea71402407e00326674505e5c5bacf35d8b3d99f09d9acb8eedd7791fc6f3d6d022b6e
@@ -5,6 +5,12 @@
5
5
  * `aasm_column` has been removed. Use `aasm.attribute_name` instead
6
6
  * `aasm_human_event_name` has been removed. Use `aasm.human_event_name` instead
7
7
 
8
+ ## 4.0.4
9
+
10
+ * corrected callback order in README
11
+ * bugfix: initialize the aasm state column after initialization of the _ActiveRecord_ instance (see [issue #191](https://github.com/aasm/aasm/issues/191) for details)
12
+ * bugfix: avoid Rails autoloading conflicts (see [issue #137](https://github.com/aasm/aasm/issues/137) and [issue #139](https://github.com/aasm/aasm/issues/139) for details)
13
+
8
14
  ## 4.0.3
9
15
 
10
16
  * bugfix: fire guards only once per transition, part 2 (see [issue #187](https://github.com/aasm/aasm/issues/187) for details)
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # AASM - Ruby state machines
2
2
 
3
- <a href="http://badge.fury.io/rb/aasm"><img src="https://badge.fury.io/rb/aasm@2x.png" alt="Gem Version" height="18"></a>
3
+ [![Gem Version](https://badge.fury.io/rb/aasm.svg)](http://badge.fury.io/rb/aasm)
4
4
  [![Build Status](https://travis-ci.org/aasm/aasm.svg?branch=master)](https://travis-ci.org/aasm/aasm)
5
- [![Code Climate](https://codeclimate.com/github/aasm/aasm.png)](https://codeclimate.com/github/aasm/aasm)
6
- [![Coverage Status](https://coveralls.io/repos/aasm/aasm/badge.png?branch=master)](https://coveralls.io/r/aasm/aasm)
5
+ [![Code Climate](https://codeclimate.com/github/aasm/aasm/badges/gpa.svg)](https://codeclimate.com/github/aasm/aasm)
6
+ [![Coverage Status](https://img.shields.io/coveralls/aasm/aasm.svg)](https://coveralls.io/r/aasm/aasm?branch=master)
7
7
 
8
8
  This package contains AASM, a library for adding finite state machines to Ruby classes.
9
9
 
@@ -145,11 +145,11 @@ begin
145
145
  transition guards
146
146
  old_state before_exit
147
147
  old_state exit
148
+ transition after
148
149
  new_state before_enter
149
150
  new_state enter
150
- ...update state...
151
- transition after
152
- event success # if persist successful
151
+ ...update state...
152
+ event success # if persist successful
153
153
  old_state after_exit
154
154
  new_state after_enter
155
155
  event after
@@ -172,7 +172,7 @@ Note that when passing arguments to a state transition, the first argument must
172
172
  In case of an error during the event processing the error is rescued and passed to `:error`
173
173
  callback, which can handle it or re-raise it for further propagation.
174
174
 
175
- During the `:on_transition` callback (and reliably only then) you can access the
175
+ During the transition's `:after` callback (and reliably only then) you can access the
176
176
  originating state (the from-state) and the target state (the to state), like this:
177
177
 
178
178
  ```ruby
@@ -13,20 +13,16 @@ Gem::Specification.new do |s|
13
13
  s.date = Time.now
14
14
  s.licenses = ["MIT"]
15
15
 
16
- # s.add_development_dependency 'activerecord', '3.2.15'
17
- # s.add_development_dependency 'activerecord', '4.0.1'
18
-
19
- # s.add_development_dependency 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
20
16
  s.add_development_dependency 'rake'
21
17
  s.add_development_dependency 'sdoc'
22
- s.add_development_dependency 'rspec', '~> 2.14'
23
- s.add_development_dependency 'rr'
24
- # s.add_development_dependency 'sqlite3'
25
- s.add_development_dependency 'minitest'
18
+ s.add_development_dependency 'rspec', '>= 2.14', '< 2.99'
19
+
20
+ # debugging
26
21
  # s.add_development_dependency 'debugger'
27
22
  # s.add_development_dependency 'pry'
28
23
 
29
- s.add_development_dependency 'mime-types', '~> 1.25' # needed by coveralls (>= 2.0 needs Ruby >=1.9.2)
24
+ # test coverage
25
+ # s.add_development_dependency 'mime-types', '~> 1.25' # needed by coveralls (>= 2.0 needs Ruby >=1.9.2)
30
26
  # s.add_development_dependency 'coveralls'
31
27
 
32
28
  s.files = `git ls-files`.split("\n")
@@ -1,17 +1,15 @@
1
1
  require 'ostruct'
2
2
 
3
- %w(
4
- version
5
- errors
6
- configuration
7
- base
8
- dsl_helper
9
- instance_base
10
- transition
11
- event
12
- state
13
- localizer
14
- state_machine
15
- persistence
16
- aasm
17
- ).each { |file| require File.join(File.dirname(__FILE__), 'aasm', file) }
3
+ require 'aasm/version'
4
+ require 'aasm/errors'
5
+ require 'aasm/configuration'
6
+ require 'aasm/base'
7
+ require 'aasm/dsl_helper'
8
+ require 'aasm/instance_base'
9
+ require 'aasm/core/transition'
10
+ require 'aasm/core/event'
11
+ require 'aasm/core/state'
12
+ require 'aasm/localizer'
13
+ require 'aasm/state_machine'
14
+ require 'aasm/persistence'
15
+ require 'aasm/aasm'
@@ -40,24 +40,6 @@ module AASM
40
40
  @aasm ||= AASM::InstanceBase.new(self)
41
41
  end
42
42
 
43
- # may be overwritten by persistence mixins
44
- def aasm_read_state
45
- # all the following lines behave like @current_state ||= aasm.enter_initial_state
46
- current = aasm.instance_variable_get("@current_state")
47
- return current if current
48
- aasm.instance_variable_set("@current_state", aasm.enter_initial_state)
49
- end
50
-
51
- # may be overwritten by persistence mixins
52
- def aasm_write_state(new_state)
53
- true
54
- end
55
-
56
- # may be overwritten by persistence mixins
57
- def aasm_write_state_without_persistence(new_state)
58
- true
59
- end
60
-
61
43
  private
62
44
 
63
45
  # Takes args and a from state and removes the first
@@ -67,7 +67,7 @@ module AASM
67
67
 
68
68
  # define an event
69
69
  def event(name, options={}, &block)
70
- @state_machine.events[name] = AASM::Event.new(name, options, &block)
70
+ @state_machine.events[name] = AASM::Core::Event.new(name, options, &block)
71
71
 
72
72
  # an addition over standard aasm so that, before firing an event, you can ask
73
73
  # may_event? and get back a boolean that tells you whether the guard method
@@ -1,4 +1,4 @@
1
- module AASM
1
+ module AASM::Core
2
2
  class Event
3
3
  include DslHelper
4
4
 
@@ -61,11 +61,11 @@ module AASM
61
61
  if definitions # define new transitions
62
62
  # Create a separate transition for each from-state to the given state
63
63
  Array(definitions[:from]).each do |s|
64
- @transitions << AASM::Transition.new(attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
64
+ @transitions << AASM::Core::Transition.new(attach_event_guards(definitions.merge(:from => s.to_sym)), &block)
65
65
  end
66
66
  # Create a transition if :to is specified without :from (transitions from ANY state)
67
67
  if @transitions.empty? && definitions[:to]
68
- @transitions << AASM::Transition.new(attach_event_guards(definitions), &block)
68
+ @transitions << AASM::Core::Transition.new(attach_event_guards(definitions), &block)
69
69
  end
70
70
  end
71
71
  @transitions
@@ -1,4 +1,4 @@
1
- module AASM
1
+ module AASM::Core
2
2
  class State
3
3
  attr_reader :name, :options
4
4
 
@@ -1,4 +1,4 @@
1
- module AASM
1
+ module AASM::Core
2
2
  class Transition
3
3
  include DslHelper
4
4
 
@@ -7,23 +7,29 @@ module AASM
7
7
  hierarchy = base.ancestors.map {|klass| klass.to_s}
8
8
 
9
9
  if hierarchy.include?("ActiveRecord::Base")
10
- require_files_for(:active_record)
11
- base.send(:include, AASM::Persistence::ActiveRecordPersistence)
10
+ include_persistence base, :active_record
12
11
  elsif hierarchy.include?("Mongoid::Document")
13
- require_files_for(:mongoid)
14
- base.send(:include, AASM::Persistence::MongoidPersistence)
12
+ include_persistence base, :mongoid
15
13
  elsif hierarchy.include?("Sequel::Model")
16
- require_files_for(:sequel)
17
- base.send(:include, AASM::Persistence::SequelPersistence)
14
+ include_persistence base, :sequel
15
+ else
16
+ include_persistence base, :plain
18
17
  end
19
18
  end
20
19
 
21
- private
20
+ private
22
21
 
23
- def require_files_for(persistence)
24
- ['base', "#{persistence}_persistence"].each do |file_name|
25
- require File.join(File.dirname(__FILE__), 'persistence', file_name)
26
- end
22
+ def include_persistence(base, type)
23
+ require File.join(File.dirname(__FILE__), 'persistence', "#{type}_persistence")
24
+ base.send(:include, constantize("AASM::Persistence::#{capitalize(type)}Persistence"))
25
+ end
26
+
27
+ def capitalize(string_or_symbol)
28
+ string_or_symbol.to_s.split('_').map {|segment| segment[0].upcase + segment[1..-1]}.join('')
29
+ end
30
+
31
+ def constantize(string)
32
+ instance_eval(string)
27
33
  end
28
34
 
29
35
  end # class << self
@@ -1,3 +1,5 @@
1
+ require_relative 'base'
2
+
1
3
  module AASM
2
4
  module Persistence
3
5
  module ActiveRecordPersistence
@@ -31,15 +33,10 @@ module AASM
31
33
  base.extend AASM::Persistence::ActiveRecordPersistence::ClassMethods
32
34
  base.send(:include, AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
33
35
 
34
- if ActiveRecord::VERSION::MAJOR >= 3
35
- base.before_validation(:aasm_ensure_initial_state, :on => :create)
36
- else
37
- base.before_validation_on_create(:aasm_ensure_initial_state)
36
+ base.after_initialize do
37
+ aasm_ensure_initial_state
38
38
  end
39
39
 
40
- # ensure initial aasm state even when validations are skipped
41
- base.before_create(:aasm_ensure_initial_state)
42
-
43
40
  # ensure state is in the list of states
44
41
  base.validate :aasm_validate_states
45
42
  end
@@ -195,5 +192,5 @@ module AASM
195
192
  end # InstanceMethods
196
193
 
197
194
  end
198
- end
199
- end
195
+ end # Persistence
196
+ end # AASM
@@ -1,3 +1,5 @@
1
+ require_relative 'base'
2
+
1
3
  module AASM
2
4
  module Persistence
3
5
  module MongoidPersistence
@@ -131,5 +133,5 @@ module AASM
131
133
  end
132
134
  end
133
135
  end
134
- end
135
- end
136
+ end # Persistence
137
+ end # AASM
@@ -0,0 +1,24 @@
1
+ module AASM
2
+ module Persistence
3
+ module PlainPersistence
4
+
5
+ def aasm_read_state
6
+ # all the following lines behave like @current_state ||= aasm.enter_initial_state
7
+ current = aasm.instance_variable_get("@current_state")
8
+ return current if current
9
+ aasm.instance_variable_set("@current_state", aasm.enter_initial_state)
10
+ end
11
+
12
+ # may be overwritten by persistence mixins
13
+ def aasm_write_state(new_state)
14
+ true
15
+ end
16
+
17
+ # may be overwritten by persistence mixins
18
+ def aasm_write_state_without_persistence(new_state)
19
+ true
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,5 @@
1
+ require_relative 'base'
2
+
1
3
  module AASM
2
4
  module Persistence
3
5
  module SequelPersistence
@@ -32,7 +32,7 @@ module AASM
32
32
  # allow reloading, extending or redefining a state
33
33
  @states.delete(name) if @states.include?(name)
34
34
 
35
- @states << AASM::State.new(name, klass, options)
35
+ @states << AASM::Core::State.new(name, klass, options)
36
36
  end
37
37
 
38
38
  private
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "4.0.3"
2
+ VERSION = "4.0.4"
3
3
  end
@@ -1,10 +1,14 @@
1
1
  ActiveRecord::Migration.suppress_messages do
2
- %w{gates readers writers transients simples simple_new_dsls no_scopes no_direct_assignments thieves localizer_test_models persisted_states provided_and_persisted_states}.each do |table_name|
2
+ %w{gates readers writers transients simples no_scopes no_direct_assignments thieves localizer_test_models persisted_states provided_and_persisted_states with_enums with_true_enums with_false_enums}.each do |table_name|
3
3
  ActiveRecord::Migration.create_table table_name, :force => true do |t|
4
4
  t.string "aasm_state"
5
5
  end
6
6
  end
7
7
 
8
+ ActiveRecord::Migration.create_table "simple_new_dsls", :force => true do |t|
9
+ t.string "status"
10
+ end
11
+
8
12
  ActiveRecord::Migration.create_table "validators", :force => true do |t|
9
13
  t.string "name"
10
14
  t.string "status"
@@ -0,0 +1,62 @@
1
+ module Callbacks
2
+ class Basic
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ end
10
+
11
+ aasm do
12
+ state :open, :initial => true,
13
+ :before_enter => :before_enter_open,
14
+ :enter => :enter_open,
15
+ :after_enter => :after_enter_open,
16
+ :before_exit => :before_exit_open,
17
+ :exit => :exit_open,
18
+ :after_exit => :after_exit_open
19
+
20
+ state :closed,
21
+ :before_enter => :before_enter_closed,
22
+ :enter => :enter_closed,
23
+ :after_enter => :after_enter_closed,
24
+ :before_exit => :before_exit_closed,
25
+ :exit => :exit_closed,
26
+ :after_exit => :after_exit_closed
27
+
28
+ event :close, :before => :before_event, :after => :after_event, :guard => :event_guard do
29
+ transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :after_transition
30
+ end
31
+
32
+ event :open, :before => :before_event, :after => :after_event do
33
+ transitions :to => :open, :from => :closed
34
+ end
35
+ end
36
+
37
+ def log(text)
38
+ puts text if @log
39
+ end
40
+
41
+ def before_enter_open; log('before_enter_open'); end
42
+ def enter_open; log('enter_open'); end
43
+ def before_exit_open; log('before_exit_open'); end
44
+ def after_enter_open; log('after_enter_open'); end
45
+ def exit_open; log('exit_open'); end
46
+ def after_exit_open; log('after_exit_open'); end
47
+
48
+ def before_enter_closed; log('before_enter_closed'); end
49
+ def enter_closed; log('enter_closed'); end
50
+ def before_exit_closed; log('before_exit_closed'); end
51
+ def exit_closed; log('exit_closed'); end
52
+ def after_enter_closed; log('after_enter_closed'); end
53
+ def after_exit_closed; log('after_exit_closed'); end
54
+
55
+ def event_guard; log('event_guard'); !@fail_event_guard; end
56
+ def transition_guard; log('transition_guard'); !@fail_transition_guard; end
57
+ def after_transition; log('after_transition'); end
58
+
59
+ def before_event; log('before_event'); end
60
+ def after_event; log('after_event'); end
61
+ end
62
+ end
@@ -0,0 +1,66 @@
1
+ module Callbacks
2
+ class GuardWithinBlock
3
+ include AASM
4
+
5
+ def initialize(options={})
6
+ @fail_event_guard = options[:fail_event_guard]
7
+ @fail_transition_guard = options[:fail_transition_guard]
8
+ @log = options[:log]
9
+ end
10
+
11
+ aasm do
12
+ state :open, :initial => true,
13
+ :before_enter => :before_enter_open,
14
+ :enter => :enter_open,
15
+ :after_enter => :after_enter_open,
16
+ :before_exit => :before_exit_open,
17
+ :exit => :exit_open,
18
+ :after_exit => :after_exit_open
19
+
20
+ state :closed,
21
+ :before_enter => :before_enter_closed,
22
+ :enter => :enter_closed,
23
+ :after_enter => :after_enter_closed,
24
+ :before_exit => :before_exit_closed,
25
+ :exit => :exit_closed,
26
+ :after_exit => :after_exit_closed
27
+
28
+ event :close, :before => :before, :after => :after, :guard => :event_guard do
29
+ transitions :to => :closed, :from => [:open], :after => :transitioning do
30
+ guard do
31
+ transition_guard
32
+ end
33
+ end
34
+ end
35
+
36
+ event :open, :before => :before, :after => :after do
37
+ transitions :to => :open, :from => :closed
38
+ end
39
+ end
40
+
41
+ def log(text)
42
+ puts text if @log
43
+ end
44
+
45
+ def before_enter_open; log('before_enter_open'); end
46
+ def enter_open; log('enter_open'); end
47
+ def before_exit_open; log('before_exit_open'); end
48
+ def after_enter_open; log('after_enter_open'); end
49
+ def exit_open; log('exit_open'); end
50
+ def after_exit_open; log('after_exit_open'); end
51
+
52
+ def before_enter_closed; log('before_enter_closed'); end
53
+ def enter_closed; log('enter_closed'); end
54
+ def before_exit_closed; log('before_exit_closed'); end
55
+ def exit_closed; log('exit_closed'); end
56
+ def after_enter_closed; log('after_enter_closed'); end
57
+ def after_exit_closed; log('after_exit_closed'); end
58
+
59
+ def event_guard; log('event_guard'); !@fail_event_guard; end
60
+ def transition_guard; log('transition_guard'); !@fail_transition_guard; end
61
+ def transitioning; log('transitioning'); end
62
+
63
+ def before; log('before'); end
64
+ def after; log('after'); end
65
+ end
66
+ end