state_machine 1.1.2 → 1.2.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.
- data/.gitignore +7 -11
- data/.travis.yml +49 -7
- data/Appraisals +255 -87
- data/CHANGELOG.md +30 -0
- data/README.md +142 -21
- data/Rakefile +1 -11
- data/examples/Gemfile +5 -0
- data/examples/Gemfile.lock +14 -0
- data/examples/auto_shop.rb +2 -0
- data/examples/car.rb +2 -0
- data/examples/doc/AutoShop.html +2856 -0
- data/examples/doc/AutoShop_state.png +0 -0
- data/examples/doc/Car.html +919 -0
- data/examples/doc/Car_state.png +0 -0
- data/examples/doc/TrafficLight.html +2230 -0
- data/examples/doc/TrafficLight_state.png +0 -0
- data/examples/doc/Vehicle.html +7921 -0
- data/examples/doc/Vehicle_state.png +0 -0
- data/examples/doc/_index.html +136 -0
- data/examples/doc/class_list.html +47 -0
- data/examples/doc/css/common.css +1 -0
- data/examples/doc/css/full_list.css +55 -0
- data/examples/doc/css/style.css +322 -0
- data/examples/doc/file_list.html +46 -0
- data/examples/doc/frames.html +13 -0
- data/examples/doc/index.html +136 -0
- data/examples/doc/js/app.js +205 -0
- data/examples/doc/js/full_list.js +173 -0
- data/examples/doc/js/jquery.js +16 -0
- data/examples/doc/method_list.html +734 -0
- data/examples/doc/top-level-namespace.html +105 -0
- data/examples/rails-rest/migration.rb +1 -5
- data/examples/rails-rest/view__form.html.erb +34 -0
- data/examples/rails-rest/view_edit.html.erb +2 -21
- data/examples/rails-rest/view_index.html.erb +6 -4
- data/examples/rails-rest/view_new.html.erb +2 -11
- data/examples/rails-rest/view_show.html.erb +5 -3
- data/examples/traffic_light.rb +2 -0
- data/examples/vehicle.rb +2 -0
- data/gemfiles/active_model-3.0.0.gemfile.lock +9 -6
- data/gemfiles/active_model-3.0.5.gemfile.lock +10 -7
- data/gemfiles/active_model-3.1.1.gemfile.lock +12 -10
- data/gemfiles/{active_model-3.2.0.gemfile → active_model-3.2.1.gemfile} +1 -1
- data/gemfiles/{graphviz-0.9.0.gemfile → active_model-3.2.12.gemfile} +1 -1
- data/gemfiles/active_model-3.2.12.gemfile.lock +36 -0
- data/gemfiles/{active_record-3.2.0.gemfile → active_model-3.2.13.rc1.gemfile} +1 -2
- data/gemfiles/active_model-3.2.13.rc1.gemfile.lock +36 -0
- data/gemfiles/active_model-4.0.0.gemfile +9 -0
- data/gemfiles/active_model-4.0.0.gemfile.lock +78 -0
- data/gemfiles/active_record-2.0.0.gemfile +2 -1
- data/gemfiles/active_record-2.0.0.gemfile.lock +15 -6
- data/gemfiles/active_record-2.0.5.gemfile +2 -1
- data/gemfiles/active_record-2.0.5.gemfile.lock +15 -6
- data/gemfiles/active_record-2.1.0.gemfile +2 -1
- data/gemfiles/active_record-2.1.0.gemfile.lock +15 -6
- data/gemfiles/active_record-2.1.2.gemfile +2 -1
- data/gemfiles/active_record-2.1.2.gemfile.lock +15 -6
- data/gemfiles/active_record-2.2.3.gemfile +2 -1
- data/gemfiles/active_record-2.2.3.gemfile.lock +15 -6
- data/gemfiles/active_record-2.3.12.gemfile +2 -1
- data/gemfiles/active_record-2.3.12.gemfile.lock +15 -6
- data/gemfiles/active_record-2.3.5.gemfile +9 -0
- data/gemfiles/active_record-2.3.5.gemfile.lock +39 -0
- data/gemfiles/active_record-3.0.0.gemfile +2 -1
- data/gemfiles/active_record-3.0.0.gemfile.lock +18 -11
- data/gemfiles/active_record-3.0.5.gemfile +2 -1
- data/gemfiles/active_record-3.0.5.gemfile.lock +19 -12
- data/gemfiles/active_record-3.1.1.gemfile +2 -1
- data/gemfiles/active_record-3.1.1.gemfile.lock +22 -16
- data/gemfiles/active_record-3.2.12.gemfile +9 -0
- data/gemfiles/active_record-3.2.12.gemfile.lock +51 -0
- data/gemfiles/active_record-3.2.13.rc1.gemfile +9 -0
- data/gemfiles/active_record-3.2.13.rc1.gemfile.lock +51 -0
- data/gemfiles/active_record-4.0.0.gemfile +11 -0
- data/gemfiles/active_record-4.0.0.gemfile.lock +83 -0
- data/gemfiles/data_mapper-0.10.2.gemfile +1 -0
- data/gemfiles/data_mapper-0.10.2.gemfile.lock +13 -9
- data/gemfiles/data_mapper-0.9.11.gemfile +1 -0
- data/gemfiles/data_mapper-0.9.11.gemfile.lock +31 -7
- data/gemfiles/data_mapper-0.9.4.gemfile.lock +25 -14
- data/gemfiles/data_mapper-0.9.7.gemfile +1 -0
- data/gemfiles/data_mapper-0.9.7.gemfile.lock +27 -15
- data/gemfiles/data_mapper-1.0.0.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.0.1.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.0.2.gemfile.lock +20 -17
- data/gemfiles/data_mapper-1.1.0.gemfile.lock +19 -16
- data/gemfiles/data_mapper-1.2.0.gemfile.lock +19 -16
- data/gemfiles/default.gemfile.lock +8 -5
- data/gemfiles/graphviz-0.9.17.gemfile +7 -0
- data/gemfiles/graphviz-0.9.17.gemfile.lock +29 -0
- data/gemfiles/graphviz-0.9.21.gemfile.lock +7 -4
- data/gemfiles/graphviz-1.0.0.gemfile.lock +7 -4
- data/gemfiles/graphviz-1.0.3.gemfile +7 -0
- data/gemfiles/graphviz-1.0.3.gemfile.lock +29 -0
- data/gemfiles/graphviz-1.0.8.gemfile +7 -0
- data/gemfiles/graphviz-1.0.8.gemfile.lock +29 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile +1 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile.lock +14 -11
- data/gemfiles/mongo_mapper-0.11.1.gemfile +7 -0
- data/gemfiles/mongo_mapper-0.11.1.gemfile.lock +44 -0
- data/gemfiles/mongo_mapper-0.11.2.gemfile +9 -0
- data/gemfiles/mongo_mapper-0.11.2.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper-0.12.0.gemfile +9 -0
- data/gemfiles/mongo_mapper-0.12.0.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +7 -4
- data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +7 -4
- data/gemfiles/mongoid-2.0.0.gemfile +2 -0
- data/gemfiles/mongoid-2.0.0.gemfile.lock +22 -18
- data/gemfiles/mongoid-2.1.4.gemfile +2 -0
- data/gemfiles/mongoid-2.1.4.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.2.4.gemfile +2 -0
- data/gemfiles/mongoid-2.2.4.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.3.3.gemfile +2 -0
- data/gemfiles/mongoid-2.3.3.gemfile.lock +21 -17
- data/gemfiles/mongoid-2.4.0.gemfile +9 -0
- data/gemfiles/mongoid-2.4.0.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.4.10.gemfile +9 -0
- data/gemfiles/mongoid-2.4.10.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.5.2.gemfile +9 -0
- data/gemfiles/mongoid-2.5.2.gemfile.lock +47 -0
- data/gemfiles/mongoid-2.6.0.gemfile +9 -0
- data/gemfiles/mongoid-2.6.0.gemfile.lock +47 -0
- data/gemfiles/mongoid-3.0.0.gemfile +8 -0
- data/gemfiles/mongoid-3.0.0.gemfile.lock +45 -0
- data/gemfiles/mongoid-3.0.22.gemfile +8 -0
- data/gemfiles/mongoid-3.0.22.gemfile.lock +45 -0
- data/gemfiles/mongoid-3.1.0.gemfile +8 -0
- data/gemfiles/mongoid-3.1.0.gemfile.lock +45 -0
- data/gemfiles/sequel-2.11.0.gemfile +2 -1
- data/gemfiles/sequel-2.11.0.gemfile.lock +11 -6
- data/gemfiles/sequel-2.12.0.gemfile +2 -1
- data/gemfiles/sequel-2.12.0.gemfile.lock +11 -6
- data/gemfiles/sequel-2.8.0.gemfile +2 -1
- data/gemfiles/sequel-2.8.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.0.0.gemfile +2 -1
- data/gemfiles/sequel-3.0.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.10.0.gemfile +9 -0
- data/gemfiles/sequel-3.10.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.13.0.gemfile +2 -1
- data/gemfiles/sequel-3.13.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.14.0.gemfile +2 -1
- data/gemfiles/sequel-3.14.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.23.0.gemfile +2 -1
- data/gemfiles/sequel-3.23.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.24.0.gemfile +2 -1
- data/gemfiles/sequel-3.24.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.29.0.gemfile +2 -1
- data/gemfiles/sequel-3.29.0.gemfile.lock +11 -6
- data/gemfiles/sequel-3.34.0.gemfile +9 -0
- data/gemfiles/sequel-3.34.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.35.0.gemfile +9 -0
- data/gemfiles/sequel-3.35.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.4.0.gemfile +9 -0
- data/gemfiles/sequel-3.4.0.gemfile.lock +33 -0
- data/gemfiles/sequel-3.44.0.gemfile +9 -0
- data/gemfiles/sequel-3.44.0.gemfile.lock +33 -0
- data/lib/state_machine.rb +6 -0
- data/lib/state_machine/branch.rb +9 -8
- data/lib/state_machine/callback.rb +2 -2
- data/lib/state_machine/core.rb +10 -0
- data/lib/state_machine/core_ext.rb +1 -0
- data/lib/state_machine/eval_helpers.rb +5 -3
- data/lib/state_machine/event.rb +17 -6
- data/lib/state_machine/graph.rb +92 -0
- data/lib/state_machine/integrations.rb +13 -1
- data/lib/state_machine/integrations/active_model.rb +14 -20
- data/lib/state_machine/integrations/active_model/observer.rb +3 -3
- data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
- data/lib/state_machine/integrations/active_record.rb +52 -25
- data/lib/state_machine/integrations/active_record/locale.rb +1 -1
- data/lib/state_machine/integrations/active_record/versions.rb +1 -17
- data/lib/state_machine/integrations/base.rb +15 -6
- data/lib/state_machine/integrations/data_mapper.rb +98 -35
- data/lib/state_machine/integrations/data_mapper/versions.rb +46 -8
- data/lib/state_machine/integrations/mongo_mapper.rb +39 -12
- data/lib/state_machine/integrations/mongo_mapper/locale.rb +1 -1
- data/lib/state_machine/integrations/mongo_mapper/versions.rb +3 -20
- data/lib/state_machine/integrations/mongoid.rb +52 -14
- data/lib/state_machine/integrations/mongoid/locale.rb +1 -1
- data/lib/state_machine/integrations/mongoid/versions.rb +52 -26
- data/lib/state_machine/integrations/sequel.rb +82 -33
- data/lib/state_machine/integrations/sequel/versions.rb +19 -44
- data/lib/state_machine/machine.rb +99 -59
- data/lib/state_machine/machine_collection.rb +1 -2
- data/lib/state_machine/macro_methods.rb +29 -0
- data/lib/state_machine/node_collection.rb +1 -1
- data/lib/state_machine/state.rb +18 -10
- data/lib/state_machine/state_context.rb +2 -2
- data/lib/state_machine/transition.rb +8 -1
- data/lib/state_machine/transition_collection.rb +2 -1
- data/lib/state_machine/version.rb +1 -1
- data/lib/state_machine/yard.rb +8 -0
- data/lib/state_machine/yard/handlers.rb +12 -0
- data/lib/state_machine/yard/handlers/base.rb +32 -0
- data/lib/state_machine/yard/handlers/event.rb +25 -0
- data/lib/state_machine/yard/handlers/machine.rb +344 -0
- data/lib/state_machine/yard/handlers/state.rb +25 -0
- data/lib/state_machine/yard/handlers/transition.rb +47 -0
- data/lib/state_machine/yard/templates.rb +3 -0
- data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
- data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
- data/lib/tasks/state_machine.rb +2 -1
- data/lib/yard-state_machine.rb +2 -0
- data/state_machine.gemspec +4 -3
- data/test/files/switch.rb +4 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/branch_test.rb +117 -36
- data/test/unit/callback_test.rb +5 -2
- data/test/unit/eval_helpers_test.rb +49 -1
- data/test/unit/event_collection_test.rb +3 -1
- data/test/unit/event_test.rb +182 -12
- data/test/unit/graph_test.rb +98 -0
- data/test/unit/integrations/active_model_test.rb +82 -12
- data/test/unit/integrations/active_record_test.rb +393 -37
- data/test/unit/integrations/base_test.rb +7 -2
- data/test/unit/integrations/data_mapper_test.rb +326 -72
- data/test/unit/integrations/mongo_mapper_test.rb +338 -44
- data/test/unit/integrations/mongoid_test.rb +606 -98
- data/test/unit/integrations/sequel_test.rb +429 -102
- data/test/unit/integrations_test.rb +28 -6
- data/test/unit/machine_collection_test.rb +6 -2
- data/test/unit/machine_test.rb +134 -82
- data/test/unit/node_collection_test.rb +2 -2
- data/test/unit/path_test.rb +1 -1
- data/test/unit/state_test.rb +65 -21
- data/test/unit/transition_collection_test.rb +43 -23
- data/test/unit/transition_test.rb +8 -2
- metadata +303 -221
- data/gemfiles/active_model-3.2.0.gemfile.lock +0 -32
- data/gemfiles/active_record-3.2.0.gemfile.lock +0 -43
- data/gemfiles/graphviz-0.9.0.gemfile.lock +0 -26
@@ -1,5 +1,5 @@
|
|
1
1
|
filename = "#{File.dirname(__FILE__)}/../active_model/locale.rb"
|
2
|
-
translations = eval(IO.read(filename), binding, filename)
|
2
|
+
translations = eval(IO.read(File.expand_path(filename)), binding, filename)
|
3
3
|
translations[:en][:activerecord] = translations[:en].delete(:activemodel)
|
4
4
|
|
5
5
|
# Only ActiveRecord 2.3.5+ can pull i18n >= 0.1.3 from system-wide gems (and
|
@@ -10,7 +10,7 @@ module StateMachine
|
|
10
10
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
11
11
|
def attributes_from_column_definition(*)
|
12
12
|
result = super
|
13
|
-
self.class.state_machines.initialize_states(self, :dynamic => false, :to => result)
|
13
|
+
self.class.state_machines.initialize_states(self, :static => :force, :dynamic => false, :to => result)
|
14
14
|
result
|
15
15
|
end
|
16
16
|
end_eval
|
@@ -81,10 +81,6 @@ module StateMachine
|
|
81
81
|
:activerecord
|
82
82
|
end
|
83
83
|
|
84
|
-
def action_hook
|
85
|
-
action == :save ? :create_or_update : super
|
86
|
-
end
|
87
|
-
|
88
84
|
def load_observer_extensions
|
89
85
|
super
|
90
86
|
::ActiveRecord::Observer.class_eval do
|
@@ -122,18 +118,6 @@ module StateMachine
|
|
122
118
|
klass.self_and_descendants_from_active_record
|
123
119
|
end
|
124
120
|
end
|
125
|
-
|
126
|
-
version '3.0.x' do
|
127
|
-
def self.active?
|
128
|
-
::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR == 0
|
129
|
-
end
|
130
|
-
|
131
|
-
def define_action_hook
|
132
|
-
# +around+ callbacks don't have direct access to results until AS 3.1
|
133
|
-
owner_class.set_callback(:save, :after, 'value', :prepend => true) if action_hook == :save
|
134
|
-
super
|
135
|
-
end
|
136
|
-
end
|
137
121
|
end
|
138
122
|
end
|
139
123
|
end
|
@@ -18,16 +18,25 @@ module StateMachine
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# Whether this integration is available for the current library. This
|
21
|
-
# is
|
22
|
-
#
|
21
|
+
# is only true if the ORM that the integration is for is currently
|
22
|
+
# defined.
|
23
23
|
def available?
|
24
|
-
|
24
|
+
matching_ancestors.any? && Object.const_defined?(matching_ancestors[0].split('::')[0])
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
28
|
-
|
27
|
+
# The list of ancestor names that cause this integration to matched.
|
28
|
+
def matching_ancestors
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Whether the integration should be used for the given class.
|
29
33
|
def matches?(klass)
|
30
|
-
|
34
|
+
matches_ancestors?(klass.ancestors.map {|ancestor| ancestor.name})
|
35
|
+
end
|
36
|
+
|
37
|
+
# Whether the integration should be used for the given list of ancestors.
|
38
|
+
def matches_ancestors?(ancestors)
|
39
|
+
(ancestors & matching_ancestors).any?
|
31
40
|
end
|
32
41
|
|
33
42
|
# Tracks the various version overrides for an integration
|
@@ -108,6 +108,42 @@ module StateMachine
|
|
108
108
|
# end
|
109
109
|
# end
|
110
110
|
#
|
111
|
+
# === Within DataMapper Hooks
|
112
|
+
#
|
113
|
+
# DataMapper protects against the potential for system stack errors resulting
|
114
|
+
# from infinite loops by preventing records from being saved multiple times
|
115
|
+
# within save hooks. You need to be acutely aware of this when interacting
|
116
|
+
# with state_machine within save hooks. There are two things to keep in mind:
|
117
|
+
#
|
118
|
+
# 1. You cannot run a state_machine event during an `after :save/:create` hook.
|
119
|
+
# 2. If you need to run a state_machine event during a `before :save/:create/etc.`
|
120
|
+
# hook, then you have to force the machine's action to be skipped by passing
|
121
|
+
# `false` in as an argument to the event.
|
122
|
+
#
|
123
|
+
# For example:
|
124
|
+
#
|
125
|
+
# class Vehicle
|
126
|
+
# include DataMapper::Resource
|
127
|
+
# ...
|
128
|
+
#
|
129
|
+
# state_machine :initial => :parked do
|
130
|
+
# event :ignite do
|
131
|
+
# transition :parked => :idling
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# # This will allow the event to transition without attempting to save a second time
|
136
|
+
# before :create { ignite(false) }
|
137
|
+
#
|
138
|
+
# # This will never work because DataMapper will refuse to save the
|
139
|
+
# # changes since we're still inside of a transaction
|
140
|
+
# # after :create { ignite }
|
141
|
+
# end
|
142
|
+
#
|
143
|
+
# While the above will work, in reality you should typically just set the
|
144
|
+
# `state_event` attribute in `#initialize` to automatically transition an
|
145
|
+
# object on creation.
|
146
|
+
#
|
111
147
|
# == Transactions
|
112
148
|
#
|
113
149
|
# By default, the use of transactions during an event transition is
|
@@ -146,21 +182,6 @@ module StateMachine
|
|
146
182
|
# end
|
147
183
|
# end
|
148
184
|
#
|
149
|
-
# If using the +save+ action for the machine, this option will be ignored as
|
150
|
-
# the transaction behavior will depend on the +save+ implementation within
|
151
|
-
# DataMapper. To avoid this, use a different action like so:
|
152
|
-
#
|
153
|
-
# class Vehicle
|
154
|
-
# include DataMapper::Resource
|
155
|
-
# ...
|
156
|
-
#
|
157
|
-
# state_machine :initial => :parked, :use_transactions => false, :action => :save_state do
|
158
|
-
# ...
|
159
|
-
# end
|
160
|
-
#
|
161
|
-
# alias_method :save_state, :save
|
162
|
-
# end
|
163
|
-
#
|
164
185
|
# == Validation errors
|
165
186
|
#
|
166
187
|
# If an event fails to successfully fire because there are no matching
|
@@ -302,26 +323,38 @@ module StateMachine
|
|
302
323
|
# The failure callback creates +TransitionLog+ records using a second
|
303
324
|
# connection to the database, allowing them to be saved without being
|
304
325
|
# affected by rollbacks in the +Vehicle+ resource's transaction.
|
326
|
+
#
|
327
|
+
# === Callback Order
|
328
|
+
#
|
329
|
+
# Callbacks occur in the following order. Callbacks specific to state_machine
|
330
|
+
# are bolded. The remaining callbacks are part of ActiveRecord.
|
331
|
+
#
|
332
|
+
# * (-) save
|
333
|
+
# * (-) begin transaction (if enabled)
|
334
|
+
# * (1) *before_transition*
|
335
|
+
# * (2) before :valid?
|
336
|
+
# * (-) valid?
|
337
|
+
# * (3) after :valid?
|
338
|
+
# * (4) before :save
|
339
|
+
# * (-) save
|
340
|
+
# * (5) before :create
|
341
|
+
# * (-) create
|
342
|
+
# * (6) after :create
|
343
|
+
# * (7) after :save
|
344
|
+
# * (8) *after_transition*
|
345
|
+
# * (-) end transaction (if enabled)
|
305
346
|
module DataMapper
|
306
347
|
include Base
|
307
348
|
|
308
349
|
require 'state_machine/integrations/data_mapper/versions'
|
309
350
|
|
310
351
|
# The default options to use for state machines using this integration
|
311
|
-
class << self; attr_reader :defaults; end
|
312
352
|
@defaults = {:action => :save, :use_transactions => false}
|
313
353
|
|
314
|
-
# Whether this integration is available. Only true if DataMapper::Resource
|
315
|
-
# is defined.
|
316
|
-
def self.available?
|
317
|
-
defined?(::DataMapper::Resource)
|
318
|
-
end
|
319
|
-
|
320
|
-
# Should this integration be used for state machines in the given class?
|
321
354
|
# Classes that include DataMapper::Resource will automatically use the
|
322
355
|
# DataMapper integration.
|
323
|
-
def self.
|
324
|
-
|
356
|
+
def self.matching_ancestors
|
357
|
+
%w(DataMapper::Resource)
|
325
358
|
end
|
326
359
|
|
327
360
|
# Loads additional files specific to DataMapper
|
@@ -371,6 +404,16 @@ module StateMachine
|
|
371
404
|
@supports_validations ||= ::DataMapper.const_defined?('Validate')
|
372
405
|
end
|
373
406
|
|
407
|
+
# Gets the db default for the machine's attribute
|
408
|
+
def owner_class_attribute_default
|
409
|
+
attribute_property && attribute_property.default
|
410
|
+
end
|
411
|
+
|
412
|
+
# Gets the property for this machine's attribute (if it exists)
|
413
|
+
def attribute_property
|
414
|
+
owner_class.properties.detect {|property| property.name == attribute}
|
415
|
+
end
|
416
|
+
|
374
417
|
# Pluralizes the name using the built-in inflector
|
375
418
|
def pluralize(word)
|
376
419
|
::DataMapper::Inflector.pluralize(word.to_s)
|
@@ -382,14 +425,14 @@ module StateMachine
|
|
382
425
|
def define_state_initializer
|
383
426
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
384
427
|
def initialize(*args)
|
385
|
-
self.class.state_machines.initialize_states(self) { super }
|
428
|
+
self.class.state_machines.initialize_states(self, :static => :force) { super }
|
386
429
|
end
|
387
430
|
end_eval
|
388
431
|
end
|
389
432
|
|
390
433
|
# Skips defining reader/writer methods since this is done automatically
|
391
434
|
def define_state_accessor
|
392
|
-
owner_class.property(attribute, String) unless
|
435
|
+
owner_class.property(attribute, String) unless attribute_property
|
393
436
|
|
394
437
|
if supports_validations?
|
395
438
|
name = self.name
|
@@ -402,20 +445,40 @@ module StateMachine
|
|
402
445
|
|
403
446
|
# Adds hooks into validation for automatically firing events
|
404
447
|
def define_action_helpers
|
405
|
-
|
406
|
-
|
407
|
-
if action == :save && supports_validations?
|
448
|
+
if action_hook == :save
|
408
449
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
409
|
-
def
|
410
|
-
self.class.state_machines.transitions(self, :save
|
450
|
+
def save(*)
|
451
|
+
result = self.class.state_machines.transitions(self, :save).perform { super }
|
452
|
+
assert_save_successful(:save, result)
|
453
|
+
result
|
454
|
+
end
|
455
|
+
|
456
|
+
def save!(*)
|
457
|
+
result = self.class.state_machines.transitions(self, :save).perform { super }
|
458
|
+
assert_save_successful(:save!, result)
|
459
|
+
result
|
460
|
+
end
|
461
|
+
|
462
|
+
def save_self(*)
|
463
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
411
464
|
end
|
412
465
|
end_eval
|
466
|
+
|
467
|
+
define_validation_hook
|
468
|
+
else
|
469
|
+
super
|
413
470
|
end
|
414
471
|
end
|
415
472
|
|
416
|
-
#
|
417
|
-
def
|
418
|
-
|
473
|
+
# Adds hooks into validation for automatically firing events
|
474
|
+
def define_validation_hook
|
475
|
+
if supports_validations?
|
476
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
477
|
+
def valid?(*)
|
478
|
+
self.class.state_machines.transitions(self, :save, :after => false).perform { super }
|
479
|
+
end
|
480
|
+
end_eval
|
481
|
+
end
|
419
482
|
end
|
420
483
|
|
421
484
|
# Creates a scope for finding records *with* a particular state or
|
@@ -1,23 +1,33 @@
|
|
1
1
|
module StateMachine
|
2
2
|
module Integrations #:nodoc:
|
3
3
|
module DataMapper
|
4
|
-
version '0.9.x' do
|
4
|
+
version '0.9.x - 0.10.x' do
|
5
5
|
def self.active?
|
6
|
-
::DataMapper::VERSION =~ /^0\.
|
6
|
+
::DataMapper::VERSION =~ /^0\.\d\./ || ::DataMapper::VERSION =~ /^0\.10\./
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def pluralize(word)
|
10
|
+
::Extlib::Inflection.pluralize(word.to_s)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
version '0.9.x
|
14
|
+
version '0.9.x' do
|
15
15
|
def self.active?
|
16
|
-
::DataMapper::VERSION =~ /^0
|
16
|
+
::DataMapper::VERSION =~ /^0\.9\./
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def define_action_helpers
|
20
|
+
if action_hook == :save
|
21
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
22
|
+
def save(*)
|
23
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
24
|
+
end
|
25
|
+
end_eval
|
26
|
+
|
27
|
+
define_validation_hook
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
@@ -33,6 +43,34 @@ module StateMachine
|
|
33
43
|
end
|
34
44
|
end
|
35
45
|
|
46
|
+
version '0.10.x' do
|
47
|
+
def self.active?
|
48
|
+
::DataMapper::VERSION =~ /^0\.10\./
|
49
|
+
end
|
50
|
+
|
51
|
+
def define_action_helpers
|
52
|
+
if action_hook == :save
|
53
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
54
|
+
def save(*)
|
55
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
56
|
+
end
|
57
|
+
|
58
|
+
def save!(*)
|
59
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
60
|
+
end
|
61
|
+
|
62
|
+
def save_self(*)
|
63
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
64
|
+
end
|
65
|
+
end_eval
|
66
|
+
|
67
|
+
define_validation_hook
|
68
|
+
else
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
36
74
|
version '1.0.0' do
|
37
75
|
def self.active?
|
38
76
|
::DataMapper::VERSION == '1.0.0'
|
@@ -233,6 +233,22 @@ module StateMachine
|
|
233
233
|
# Note, also, that the transition can be accessed by simply defining
|
234
234
|
# additional arguments in the callback block.
|
235
235
|
#
|
236
|
+
# === Callback Order
|
237
|
+
#
|
238
|
+
# Callbacks occur in the following order. Callbacks specific to state_machine
|
239
|
+
# are bolded. The remaining callbacks are part of MongoMapper.
|
240
|
+
#
|
241
|
+
# * (-) save
|
242
|
+
# * (1) *before_transition*
|
243
|
+
# * (-) valid
|
244
|
+
# * (2) before_validation
|
245
|
+
# * (3) after_validation
|
246
|
+
# * (4) before_save
|
247
|
+
# * (5) before_create
|
248
|
+
# * (6) after_create
|
249
|
+
# * (7) after_save
|
250
|
+
# * (8) *after_transition*
|
251
|
+
#
|
236
252
|
# == Internationalization
|
237
253
|
#
|
238
254
|
# Any error message that is generated from performing invalid transitions
|
@@ -291,17 +307,10 @@ module StateMachine
|
|
291
307
|
# The default options to use for state machines using this integration
|
292
308
|
@defaults = {:action => :save}
|
293
309
|
|
294
|
-
# Whether this integration is available. Only true if MongoMapper::Document
|
295
|
-
# is defined.
|
296
|
-
def self.available?
|
297
|
-
defined?(::MongoMapper::Document)
|
298
|
-
end
|
299
|
-
|
300
|
-
# Should this integration be used for state machines in the given class?
|
301
310
|
# Classes that include MongoMapper::Document will automatically use the
|
302
311
|
# MongoMapper integration.
|
303
|
-
def self.
|
304
|
-
|
312
|
+
def self.matching_ancestors
|
313
|
+
%w(MongoMapper::Document)
|
305
314
|
end
|
306
315
|
|
307
316
|
protected
|
@@ -310,27 +319,45 @@ module StateMachine
|
|
310
319
|
action == :save
|
311
320
|
end
|
312
321
|
|
322
|
+
# Gets the db default for the machine's attribute
|
323
|
+
def owner_class_attribute_default
|
324
|
+
attribute_key && attribute_key.default_value
|
325
|
+
end
|
326
|
+
|
327
|
+
# Gets the Mongoid key for this machine's attribute (if it exists)
|
328
|
+
def attribute_key
|
329
|
+
owner_class.keys[attribute.to_s]
|
330
|
+
end
|
331
|
+
|
313
332
|
# Defines an initialization hook into the owner class for setting the
|
314
333
|
# initial state of the machine *before* any attributes are set on the
|
315
334
|
# object
|
316
335
|
def define_state_initializer
|
317
336
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
318
337
|
def initialize(*args)
|
319
|
-
self.class.state_machines.initialize_states(self) { super }
|
338
|
+
self.class.state_machines.initialize_states(self, :static => :force) { super }
|
320
339
|
end
|
321
340
|
end_eval
|
322
341
|
end
|
323
342
|
|
324
343
|
# Skips defining reader/writer methods since this is done automatically
|
325
344
|
def define_state_accessor
|
326
|
-
owner_class.key(attribute, String) unless
|
345
|
+
owner_class.key(attribute, String) unless attribute_key
|
327
346
|
super
|
328
347
|
end
|
329
348
|
|
330
349
|
# Uses around callbacks to run state events if using the :save hook
|
331
350
|
def define_action_hook
|
332
351
|
if action_hook == :save
|
333
|
-
|
352
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
353
|
+
def save(*)
|
354
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super }
|
355
|
+
end
|
356
|
+
|
357
|
+
def save!(*)
|
358
|
+
self.class.state_machine(#{name.inspect}).send(:around_save, self) { super } || raise(::MongoMapper::DocumentNotValid.new(self))
|
359
|
+
end
|
360
|
+
end_eval
|
334
361
|
else
|
335
362
|
super
|
336
363
|
end
|
@@ -1,4 +1,4 @@
|
|
1
1
|
filename = "#{File.dirname(__FILE__)}/../active_model/locale.rb"
|
2
|
-
translations = eval(IO.read(filename), binding, filename)
|
2
|
+
translations = eval(IO.read(File.expand_path(filename)), binding, filename)
|
3
3
|
translations[:en][:mongo_mapper] = translations[:en].delete(:activemodel)
|
4
4
|
translations
|
@@ -14,7 +14,7 @@ module StateMachine
|
|
14
14
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
15
15
|
def initialize(*args)
|
16
16
|
attrs, * = args
|
17
|
-
attrs && attrs.stringify_keys.key?('_id') ? super : self.class.state_machines.initialize_states(self) { super }
|
17
|
+
attrs && attrs.stringify_keys.key?('_id') ? super : self.class.state_machines.initialize_states(self, :static => :force) { super }
|
18
18
|
end
|
19
19
|
end_eval
|
20
20
|
end
|
@@ -49,10 +49,6 @@ module StateMachine
|
|
49
49
|
})
|
50
50
|
end
|
51
51
|
|
52
|
-
def action_hook
|
53
|
-
action == :save ? :create_or_update : super
|
54
|
-
end
|
55
|
-
|
56
52
|
def load_locale
|
57
53
|
end
|
58
54
|
|
@@ -82,25 +78,12 @@ module StateMachine
|
|
82
78
|
def define_state_initializer
|
83
79
|
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
84
80
|
def initialize(*args)
|
85
|
-
|
86
|
-
from_db ? super : self.class.state_machines.initialize_states(self) { super }
|
81
|
+
from_db = args[1]
|
82
|
+
from_db ? super : self.class.state_machines.initialize_states(self, :static => :force) { super }
|
87
83
|
end
|
88
84
|
end_eval
|
89
85
|
end
|
90
86
|
end
|
91
|
-
|
92
|
-
# Assumes MongoMapper 0.10+ uses ActiveModel 3.1+
|
93
|
-
version '0.9.x' do
|
94
|
-
def self.active?
|
95
|
-
defined?(::MongoMapper::Version) && ::MongoMapper::Version =~ /^0\.9\./
|
96
|
-
end
|
97
|
-
|
98
|
-
def define_action_hook
|
99
|
-
# +around+ callbacks don't have direct access to results until AS 3.1
|
100
|
-
owner_class.set_callback(:save, :after, 'value', :prepend => true) if action_hook == :save
|
101
|
-
super
|
102
|
-
end
|
103
|
-
end
|
104
87
|
end
|
105
88
|
end
|
106
89
|
end
|