aasm 3.0.13 → 3.0.14

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.
@@ -0,0 +1,46 @@
1
+ module AASM
2
+ module Persistence
3
+ module Base
4
+
5
+ module ClassMethods
6
+ # Maps to the aasm_column in the database. Defaults to "aasm_state". You can write
7
+ # (example provided here for ActiveRecord, but it's true for Mongoid as well):
8
+ #
9
+ # create_table :foos do |t|
10
+ # t.string :name
11
+ # t.string :aasm_state
12
+ # end
13
+ #
14
+ # class Foo < ActiveRecord::Base
15
+ # include AASM
16
+ # end
17
+ #
18
+ # OR:
19
+ #
20
+ # create_table :foos do |t|
21
+ # t.string :name
22
+ # t.string :status
23
+ # end
24
+ #
25
+ # class Foo < ActiveRecord::Base
26
+ # include AASM
27
+ # aasm_column :status
28
+ # end
29
+ #
30
+ # This method is both a getter and a setter
31
+ def aasm_column(column_name=nil)
32
+ if column_name
33
+ AASM::StateMachine[self].config.column = column_name.to_sym
34
+ # @aasm_column = column_name.to_sym
35
+ else
36
+ AASM::StateMachine[self].config.column ||= :aasm_state
37
+ # @aasm_column ||= :aasm_state
38
+ end
39
+ # @aasm_column
40
+ AASM::StateMachine[self].config.column
41
+ end
42
+ end
43
+
44
+ end # Base
45
+ end # Persistence
46
+ end # AASM
@@ -34,15 +34,16 @@ module AASM
34
34
  # end
35
35
  #
36
36
  def self.included(base)
37
+ base.extend AASM::Persistence::Base::ClassMethods
37
38
  base.extend AASM::Persistence::MongoidPersistence::ClassMethods
38
39
  base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
39
- base.send(:include, AASM::Persistence::MongoidPersistence::ReadState) unless base.method_defined?(:aasm_read_state)
40
+ base.send(:include, AASM::Persistence::ReadState) unless base.method_defined?(:aasm_read_state)
40
41
  base.send(:include, AASM::Persistence::MongoidPersistence::WriteState) unless base.method_defined?(:aasm_write_state)
41
42
  base.send(:include, AASM::Persistence::MongoidPersistence::WriteStateWithoutPersistence) unless base.method_defined?(:aasm_write_state_without_persistence)
42
43
 
43
44
  # if base.respond_to?(:named_scope)
44
45
  # base.extend(AASM::Persistence::MongoidPersistence::NamedScopeMethods)
45
- #
46
+ #
46
47
  # base.class_eval do
47
48
  # class << self
48
49
  # unless method_defined?(:aasm_state_without_named_scope)
@@ -59,60 +60,6 @@ module AASM
59
60
  end
60
61
 
61
62
  module ClassMethods
62
- # Maps to the aasm_column in the database. Deafults to "aasm_state". You can write:
63
- #
64
- # class Foo
65
- # include Mongoid::Document
66
- # include AASM
67
- # field :aasm_state
68
- # end
69
- #
70
- # OR:
71
- #
72
- # class Foo
73
- # include Mongoid::Document
74
- # include AASM
75
- # field :status
76
- # aasm_column :status
77
- # end
78
- #
79
- # This method is both a getter and a setter
80
- def aasm_column(column_name=nil)
81
- if column_name
82
- AASM::StateMachine[self].config.column = column_name.to_sym
83
- # @aasm_column = column_name.to_sym
84
- else
85
- AASM::StateMachine[self].config.column ||= :aasm_state
86
- # @aasm_column ||= :aasm_state
87
- end
88
- # @aasm_column
89
- AASM::StateMachine[self].config.column
90
- end
91
-
92
- # def find_in_state(number, state, *args)
93
- # with_state_scope state do
94
- # find(number, *args)
95
- # end
96
- # end
97
- #
98
- # def count_in_state(state, *args)
99
- # with_state_scope state do
100
- # count(*args)
101
- # end
102
- # end
103
- #
104
- # def calculate_in_state(state, *args)
105
- # with_state_scope state do
106
- # calculate(*args)
107
- # end
108
- # end
109
-
110
- protected
111
- def with_state_scope(state)
112
- with_scope :find => {:conditions => ["#{table_name}.#{aasm_column} = ?", state.to_s]} do
113
- yield if block_given?
114
- end
115
- end
116
63
  end
117
64
 
118
65
  module InstanceMethods
@@ -200,42 +147,6 @@ module AASM
200
147
  end
201
148
  end
202
149
 
203
- module ReadState
204
-
205
- # Returns the value of the aasm_column - called from <tt>aasm_current_state</tt>
206
- #
207
- # If it's a new record, and the aasm state column is blank it returns the initial state:
208
- #
209
- # class Foo
210
- # include Mongoid::Document
211
- # include AASM
212
- # aasm_column :status
213
- # aasm_state :opened
214
- # aasm_state :closed
215
- # end
216
- #
217
- # foo = Foo.new
218
- # foo.current_state # => :opened
219
- # foo.close
220
- # foo.current_state # => :closed
221
- #
222
- # foo = Foo.find(1)
223
- # foo.current_state # => :opened
224
- # foo.aasm_state = nil
225
- # foo.current_state # => nil
226
- #
227
- # NOTE: intended to be called from an event
228
- #
229
- # This allows for nil aasm states - be sure to add validation to your model
230
- def aasm_read_state
231
- if new_record?
232
- send(self.class.aasm_column).blank? ? aasm_determine_state_name(self.class.aasm_initial_state) : send(self.class.aasm_column).to_sym
233
- else
234
- send(self.class.aasm_column).nil? ? nil : send(self.class.aasm_column).to_sym
235
- end
236
- end
237
- end
238
-
239
150
  module NamedScopeMethods
240
151
  def aasm_state_with_named_scope name, options = {}
241
152
  aasm_state_without_named_scope name, options
@@ -0,0 +1,40 @@
1
+ module AASM
2
+ module Persistence
3
+ module ReadState
4
+
5
+ # Returns the value of the aasm_column - called from <tt>aasm_current_state</tt>
6
+ #
7
+ # If it's a new record, and the aasm state column is blank it returns the initial state
8
+ # (example provided here for ActiveRecord, but it's true for Mongoid as well):
9
+ #
10
+ # class Foo < ActiveRecord::Base
11
+ # include AASM
12
+ # aasm_column :status
13
+ # aasm_state :opened
14
+ # aasm_state :closed
15
+ # end
16
+ #
17
+ # foo = Foo.new
18
+ # foo.current_state # => :opened
19
+ # foo.close
20
+ # foo.current_state # => :closed
21
+ #
22
+ # foo = Foo.find(1)
23
+ # foo.current_state # => :opened
24
+ # foo.aasm_state = nil
25
+ # foo.current_state # => nil
26
+ #
27
+ # NOTE: intended to be called from an event
28
+ #
29
+ # This allows for nil aasm states - be sure to add validation to your model
30
+ def aasm_read_state
31
+ if new_record?
32
+ send(self.class.aasm_column).blank? ? aasm_determine_state_name(self.class.aasm_initial_state) : send(self.class.aasm_column).to_sym
33
+ else
34
+ send(self.class.aasm_column).nil? ? nil : send(self.class.aasm_column).to_sym
35
+ end
36
+ end
37
+
38
+ end # ReadState
39
+ end # Persistence
40
+ end # AASM
@@ -15,19 +15,23 @@ module AASM
15
15
  def may_fire?(obj, to_state=nil, *args)
16
16
  _fire(obj, true, to_state, *args) # true indicates test firing
17
17
  end
18
-
18
+
19
19
  def fire(obj, to_state=nil, *args)
20
20
  _fire(obj, false, to_state, *args) # false indicates this is not a test (fire!)
21
21
  end
22
22
 
23
23
  def transitions_from_state?(state)
24
- @transitions.any? { |t| t.from == state }
24
+ transitions_from_state(state).any?
25
25
  end
26
26
 
27
27
  def transitions_from_state(state)
28
28
  @transitions.select { |t| t.from == state }
29
29
  end
30
30
 
31
+ def transitions_to_state?(state)
32
+ transitions_to_state(state).any?
33
+ end
34
+
31
35
  def transitions_to_state(state)
32
36
  @transitions.select { |t| t.to == state }
33
37
  end
@@ -6,23 +6,27 @@ module AASM
6
6
  list << :"#{i18n_scope(klass)}.events.#{i18n_klass(ancestor)}.#{event}"
7
7
  list
8
8
  end
9
- (0...(checklist.size-1)).each do |i|
10
- begin
11
- return I18n.translate(checklist.shift, :raise => true)
12
- rescue I18n::MissingTranslationData
13
- # that's okay
14
- end
15
- end
16
- I18n.translate(checklist.shift, :default => event.to_s.humanize)
9
+ translate_queue(checklist) || I18n.translate(checklist.shift, :default => event.to_s.humanize)
17
10
  end
18
11
 
19
12
  def human_state(obj)
20
13
  klass = obj.class
21
14
  checklist = ancestors_list(klass).inject([]) do |list, ancestor|
22
- list << :"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}/#{obj.aasm_current_state}"
23
- list << :"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}.#{obj.aasm_current_state}"
15
+ list << item_for(obj, klass, ancestor)
16
+ list << item_for(obj, klass, ancestor, :old_style => true)
24
17
  list
25
18
  end
19
+ translate_queue(checklist) || I18n.translate(checklist.shift, :default => obj.aasm_current_state.to_s.humanize)
20
+ end
21
+
22
+ private
23
+
24
+ def item_for(obj, klass, ancestor, options={})
25
+ separator = options[:old_style] ? '.' : '/'
26
+ :"#{i18n_scope(klass)}.attributes.#{i18n_klass(ancestor)}.#{klass.aasm_column}#{separator}#{obj.aasm_current_state}"
27
+ end
28
+
29
+ def translate_queue(checklist)
26
30
  (0...(checklist.size-1)).each do |i|
27
31
  begin
28
32
  return I18n.translate(checklist.shift, :raise => true)
@@ -30,11 +34,9 @@ module AASM
30
34
  # that's okay
31
35
  end
32
36
  end
33
- I18n.translate(checklist.shift, :default => obj.aasm_current_state.to_s.humanize)
37
+ nil
34
38
  end
35
39
 
36
- private
37
-
38
40
  # added for rails 2.x compatibility
39
41
  def i18n_scope(klass)
40
42
  klass.respond_to?(:i18n_scope) ? klass.i18n_scope : :activerecord
@@ -16,6 +16,14 @@ module AASM
16
16
  end
17
17
  end
18
18
 
19
+ def <=>(state)
20
+ if state.is_a? Symbol
21
+ name <=> state
22
+ else
23
+ name <=> state.name
24
+ end
25
+ end
26
+
19
27
  def fire_callbacks(action, record)
20
28
  action = @options[action]
21
29
  catch :halt_aasm_chain do
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "3.0.13"
2
+ VERSION = "3.0.14"
3
3
  end
@@ -0,0 +1,84 @@
1
+ class AuthMachine
2
+ include AASM
3
+
4
+ attr_accessor :activation_code, :activated_at, :deleted_at
5
+
6
+ aasm do
7
+ state :passive
8
+ state :pending, :initial => true, :enter => :make_activation_code
9
+ state :active, :enter => :do_activate
10
+ state :suspended
11
+ state :deleted, :enter => :do_delete, :exit => :do_undelete
12
+ state :waiting
13
+
14
+ event :register do
15
+ transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| u.can_register? }
16
+ end
17
+
18
+ event :activate do
19
+ transitions :from => :pending, :to => :active
20
+ end
21
+
22
+ event :suspend do
23
+ transitions :from => [:passive, :pending, :active], :to => :suspended
24
+ end
25
+
26
+ event :delete do
27
+ transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted
28
+ end
29
+
30
+ # a dummy event that can never happen
31
+ event :unpassify do
32
+ transitions :from => :passive, :to => :active, :guard => Proc.new {|u| false }
33
+ end
34
+
35
+ event :unsuspend do
36
+ transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| u.has_activated? }
37
+ transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| u.has_activation_code? }
38
+ transitions :from => :suspended, :to => :passive
39
+ end
40
+
41
+ event :wait do
42
+ transitions :from => :suspended, :to => :waiting, :guard => :if_polite?
43
+ end
44
+ end
45
+
46
+ def initialize
47
+ # the AR backend uses a before_validate_on_create :aasm_ensure_initial_state
48
+ # lets do something similar here for testing purposes.
49
+ aasm_enter_initial_state
50
+ end
51
+
52
+ def make_activation_code
53
+ @activation_code = 'moo'
54
+ end
55
+
56
+ def do_activate
57
+ @activated_at = Time.now
58
+ @activation_code = nil
59
+ end
60
+
61
+ def do_delete
62
+ @deleted_at = Time.now
63
+ end
64
+
65
+ def do_undelete
66
+ @deleted_at = false
67
+ end
68
+
69
+ def can_register?
70
+ true
71
+ end
72
+
73
+ def has_activated?
74
+ !!@activated_at
75
+ end
76
+
77
+ def has_activation_code?
78
+ !!@activation_code
79
+ end
80
+
81
+ def if_polite?(phrase = nil)
82
+ phrase == :please
83
+ end
84
+ end
@@ -0,0 +1,38 @@
1
+ class CallbackNewDsl
2
+ include AASM
3
+
4
+ aasm do
5
+ state :open, :initial => true,
6
+ :before_enter => :before_enter_open,
7
+ :after_enter => :after_enter_open,
8
+ :before_exit => :before_exit_open,
9
+ :after_exit => :after_exit_open
10
+
11
+ state :closed,
12
+ :before_enter => :before_enter_closed,
13
+ :after_enter => :after_enter_closed,
14
+ :before_exit => :before_exit_closed,
15
+ :after_exit => :after_exit_closed
16
+
17
+ event :close, :before => :before, :after => :after do
18
+ transitions :to => :closed, :from => [:open]
19
+ end
20
+
21
+ event :open, :before => :before, :after => :after do
22
+ transitions :to => :open, :from => :closed
23
+ end
24
+ end
25
+
26
+ def before_enter_open; end
27
+ def before_exit_open; end
28
+ def after_enter_open; end
29
+ def after_exit_open; end
30
+
31
+ def before_enter_closed; end
32
+ def before_exit_closed; end
33
+ def after_enter_closed; end
34
+ def after_exit_closed; end
35
+
36
+ def before; end
37
+ def after; end
38
+ end
@@ -0,0 +1,36 @@
1
+ class CallbackOldDsl
2
+ include AASM
3
+
4
+ aasm_initial_state :open
5
+ aasm_state :open,
6
+ :before_enter => :before_enter_open,
7
+ :before_exit => :before_exit_open,
8
+ :after_enter => :after_enter_open,
9
+ :after_exit => :after_exit_open
10
+ aasm_state :closed,
11
+ :before_enter => :before_enter_closed,
12
+ :before_exit => :before_exit_closed,
13
+ :after_enter => :after_enter_closed,
14
+ :after_exit => :after_exit_closed
15
+
16
+ aasm_event :close, :before => :before, :after => :after do
17
+ transitions :to => :closed, :from => [:open]
18
+ end
19
+
20
+ aasm_event :open, :before => :before, :after => :after do
21
+ transitions :to => :open, :from => :closed
22
+ end
23
+
24
+ def before_enter_open; end
25
+ def before_exit_open; end
26
+ def after_enter_open; end
27
+ def after_exit_open; end
28
+
29
+ def before_enter_closed; end
30
+ def before_exit_closed; end
31
+ def after_enter_closed; end
32
+ def after_exit_closed; end
33
+
34
+ def before; end
35
+ def after; end
36
+ end