rails-workflow 1.4.2.4 → 1.4.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44851c558cacf48d320f22b1b2f644507999f8ac
4
- data.tar.gz: 034320eef361e79282e3a215094c99733b079fbf
3
+ metadata.gz: fef57b053c2e5b632d435a9e6c98dc8da4b28117
4
+ data.tar.gz: 90121871ed2d3df2a3417276683a36a44687d87a
5
5
  SHA512:
6
- metadata.gz: 46d9a44561d2959736533d1d2095756420a3bd15b6449e19fc09ccb4a741d998c9e4c76aaeb32b7f4fce1ee5bc0fa9e16da135fb3bb76cc17a2b2930171085af
7
- data.tar.gz: 097c8593b99ea4512f983bf0f40f961ee31e21b23d8b115c6dbde809896e6b96ec2e23f1d0aa25774d172a74eec2477d3bb5169bd69289bf42f1a2d903a52a9c
6
+ metadata.gz: b7c57936b5570cc3c0eea2973a07cdc1419333d3e02ca370c2a69fe49aafe151b33d0d53bc43304fdc32ac7f46c0bf541687c525955f2652f6ad735a873cfc69
7
+ data.tar.gz: 159494b51e3e3ce814b34390f25fbc4e367993b893beb2bb517e161e3c7b50f2d38c3c3b7ccaa7dfa9d4c752317839d62fc7c825f7f0334019f57497efafce05
data/.gitignore CHANGED
@@ -20,3 +20,5 @@ test/version_tmp
20
20
  tmp
21
21
 
22
22
  .byebug_history
23
+
24
+ lib/active_support/callbacks.rb
data/README.markdown CHANGED
@@ -298,24 +298,78 @@ The three callback classes accept `:only` and `:except` parameters, and treat th
298
298
  ## Parameterized Callbacks
299
299
 
300
300
  If you're passing parameters through the `transition!` method, you can receive
301
- them easily in your callbacks. For example:
301
+ them easily in your callbacks. Workflow::Callbacks will inspect the parameters of
302
+ your block or method and pass just the ones you ask for.
303
+
304
+ Three magic names apply to parameter names defined on callbacks:
305
+
306
+ * `event` will be set to the name of the event being processed.
307
+ * `to` will be set to the name of the destination state.
308
+ * `from` will be set to the name of the state being exited.
309
+
310
+ Other parameters will be `shift`ed from what you pass in, so they should be taken
311
+ back in order. As in:
302
312
 
303
313
  ```ruby
304
- class Article
305
- include Workflow
306
- workflow do
307
- event_args :review_date
314
+ def my_after_submit(from, cool, *args)
315
+ logger.warn [from, cool, args]
316
+ end
317
+ after_transition :my_after_submit, only: :submit
318
+
319
+ an_article.submit! :rad, 1, 2, 3
320
+ # => [:submit, :rad, [1, 2, 3]]
321
+ ```
322
+
323
+ You can also use keyword arguments:
324
+
325
+ ```ruby
326
+ def my_after_submit(to, hype:, **args)
327
+ logger.warn [to, hype, args]
308
328
  end
329
+ after_transition :my_after_submit, only: :submit
330
+
331
+ an_article.submit! a: 1, b: 2, hype: 4.5, c: 3
332
+ # => [:awaiting_review, 4.5, {a: 1, b: 2, c: 3}]
333
+ ```
334
+
335
+ Around callbacks should be sure to yield the block given:
336
+
337
+ ```ruby
338
+ after_transition :my_after_submit, only: :submit
339
+
340
+ def my_after_submit(to, hype:, **args)
341
+ logger.warn [to, hype, args]
342
+ yield
343
+ end
344
+
345
+ def my_after_submit(to, hype:, **args, &bloci)
346
+ logger.warn [to, hype, args]
347
+ block.call
348
+ end
349
+
350
+ ```
351
+
352
+ Note that in order to use block-style callbacks with special arguments, unless you
353
+ use strictly keyword arguments, the first
354
+ parameters to your block must be the object and callback block (for around callbacks):
355
+
356
+ ```ruby
309
357
  before_transition do |reviewer:|
310
358
  logger.debug reviewer.name
311
359
  end
312
- after_transition do |author:, **arguments|
313
- logger.debug arguments[:reviewer].name
314
- logger.debug author.name
360
+ Article.last.transition! :submit, reviewer: current_user
361
+
362
+ before_transition do |obj, reviewer|
363
+ logger.debug reviewer.name
364
+ end
365
+ Article.last.transition! :submit, current_user
366
+
367
+ around_transition do |obj, callbacks, reviewer|
368
+ logger.debug reviewer.name
369
+ callbacks.call
315
370
  end
316
- end
371
+ Article.last.transition! :submit, current_user
317
372
 
318
- Article.last.transition! :submit, reviewer: current_user
319
373
  ```
320
374
 
321
375
  If you don't like keyword arguments you can use standard arguments, but you
data/bin/console CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bundler/setup"
4
4
  require "workflow"
5
+
5
6
  # You can add fixtures and/or initialization code here to make experimenting
6
7
  # with your gem easier. You can also use a different console, if you like.
7
8
 
data/bin/deploy ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ rm *.gem
4
+ gem build `ls *.gemspec`
5
+ gem push `ls *.gem`
data/lib/workflow.rb CHANGED
@@ -18,6 +18,29 @@ module Workflow
18
18
  include Callbacks
19
19
  include Errors
20
20
 
21
+ module ComputeIdentifier
22
+ private
23
+ def make_lambda(filter)
24
+ if filter.kind_of? Workflow::Callbacks::TransitionCallbackWrapper
25
+ super(filter.wrapper)
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def compute_identifier(filter)
32
+ if filter.kind_of? Workflow::Callbacks::TransitionCallbackWrapper
33
+ super(filter.raw_proc)
34
+ else
35
+ super
36
+ end
37
+ end
38
+ end
39
+
40
+ class ::ActiveSupport::Callbacks::Callback
41
+ prepend ComputeIdentifier
42
+ end
43
+
21
44
  def self.configure(&block)
22
45
  block.call(config) if block_given?
23
46
  end
@@ -1,5 +1,6 @@
1
1
  require 'workflow/callbacks/callback'
2
2
  require 'workflow/callbacks/transition_callback_wrapper'
3
+ require 'workflow/callbacks/transition_callback_method_wrapper'
3
4
 
4
5
  module Workflow
5
6
  module Callbacks
@@ -246,13 +247,13 @@ module Workflow
246
247
  CALLBACK_MAP.each do |type, context_attribute|
247
248
  define_method "#{callback}_#{type}" do |*names, &blk|
248
249
  _insert_callbacks(names, context_attribute, blk) do |name, options|
249
- set_callback(type, callback, TransitionCallbackWrapper.build_wrapper(callback, name), options)
250
+ set_callback(type, callback, TransitionCallbackWrapper.build_wrapper(callback, name, self), options)
250
251
  end
251
252
  end
252
253
 
253
254
  define_method "prepend_#{callback}_#{type}" do |*names, &blk|
254
255
  _insert_callbacks(names, context_attribute, blk) do |name, options|
255
- set_callback(type, callback, TransitionCallbackWrapper.build_wrapper(callback, name), options.merge(prepend: true))
256
+ set_callback(type, callback, TransitionCallbackWrapper.build_wrapper(callback, name, self), options.merge(prepend: true))
256
257
  end
257
258
  end
258
259
 
@@ -260,7 +261,7 @@ module Workflow
260
261
  # for details on the allowed parameters.
261
262
  define_method "skip_#{callback}_#{type}" do |*names|
262
263
  _insert_callbacks(names, context_attribute) do |name, options|
263
- skip_callback(type, callback, TransitionCallbackWrapper.build_wrapper(callback, name), options)
264
+ skip_callback(type, callback, name, options)
264
265
  end
265
266
  end
266
267
 
@@ -0,0 +1,65 @@
1
+ module Workflow
2
+ module Callbacks
3
+ class TransitionCallbackMethodWrapper < TransitionCallbackWrapper
4
+ attr_reader :calling_class
5
+
6
+ def wrapper
7
+ cb_object = self
8
+ proc_string = build_proc(<<-EOF)
9
+ arguments = [
10
+ cb_object.send(:raw_proc).inspect,
11
+ cb_object.send(:name_arguments_string),
12
+ cb_object.send(:rest_param_string),
13
+ cb_object.send(:kw_arguments_string),
14
+ cb_object.send(:keyrest_string),
15
+ cb_object.send(:procedure_string)].compact.join(', ')
16
+ target.instance_eval("send(\#{arguments})")
17
+ EOF
18
+ p = eval(proc_string)
19
+ return overload_equality_operator(p)
20
+ end
21
+
22
+ # protected
23
+
24
+ def overload_equality_operator(outer_proc)
25
+ raw_proc = raw_proc
26
+ def outer_proc.raw_proc
27
+ raw_proc
28
+ end
29
+ def outer_proc.==(other)
30
+ if other.kind_of?(::Proc)
31
+ if other.respond_to?(:raw_proc)
32
+ self.raw_proc == other.raw_proc
33
+ else
34
+ self == other
35
+ end
36
+ elsif other.kind_of?(Symbol)
37
+ self.raw_proc == other
38
+ else
39
+ false
40
+ end
41
+ end
42
+ return outer_proc
43
+ end
44
+ def name_arguments_string
45
+ name_params.map{|name| "name_proc.call(:#{name})"} if name_params.any?
46
+ end
47
+
48
+ def procedure_string
49
+ '&callbacks' if around_callback?
50
+ end
51
+
52
+ def callback_method
53
+ @meth ||= calling_class.instance_method(raw_proc)
54
+ end
55
+
56
+ def parameters
57
+ callback_method.parameters
58
+ end
59
+
60
+ def arity
61
+ callback_method.arity
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,17 +1,21 @@
1
+
1
2
  module Workflow
2
3
  module Callbacks
3
4
  class TransitionCallbackWrapper
4
- attr_reader :callback_type, :inner_procedure
5
- def initialize(callback_type, inner_procedure)
5
+ attr_reader :callback_type, :raw_proc
6
+ def initialize(callback_type, raw_proc, calling_class)
6
7
  @callback_type = callback_type
7
- @inner_procedure = inner_procedure
8
+ @raw_proc = raw_proc
9
+ @calling_class = calling_class
8
10
  end
9
11
 
10
- def self.build_wrapper(callback_type, inner_procedure)
11
- if inner_procedure.kind_of? ::Proc
12
- new(callback_type, inner_procedure).wrapper
12
+ def self.build_wrapper(callback_type, raw_proc, calling_class)
13
+ if raw_proc.kind_of? ::Proc
14
+ new(callback_type, raw_proc, calling_class).wrapper
15
+ elsif raw_proc.kind_of? ::Symbol
16
+ TransitionCallbackMethodWrapper.new(callback_type, raw_proc, calling_class)
13
17
  else
14
- inner_procedure
18
+ raw_proc
15
19
  end
16
20
  end
17
21
 
@@ -23,21 +27,30 @@ module Workflow
23
27
  keyrest_string,
24
28
  procedure_string].compact.join(', ')
25
29
 
26
- inner_procedure = self.inner_procedure
27
- str = <<-EOF
30
+ raw_proc = self.raw_proc
31
+ str = build_proc("target.instance_exec(#{arguments})")
32
+ eval(str)
33
+ end
34
+
35
+ protected
36
+
37
+ def build_proc(proc_body)
38
+ <<-EOF
28
39
  Proc.new do |target#{', callbacks' if around_callback?}|
29
- attributes = transition_context.attributes.dup
30
- event_args = transition_context.event_args.dup
31
- name_arg = -> (name) { attributes.delete(name) || event_args.shift }
32
- target.instance_exec(#{arguments})
40
+ from, to, event, event_args, attributes = transition_context.values
41
+ name_proc = Proc.new {|name|
42
+ case name
43
+ when :to then to
44
+ when :from then from
45
+ when :event then event
46
+ else (attributes.delete(name) || event_args.shift)
47
+ end
48
+ }
49
+ #{proc_body}
33
50
  end
34
51
  EOF
35
- # puts str
36
- eval(str)
37
52
  end
38
53
 
39
- private
40
-
41
54
  def around_callback?
42
55
  callback_type == :around
43
56
  end
@@ -47,7 +60,7 @@ module Workflow
47
60
  names = []
48
61
  names << 'target' if params.shift
49
62
  (names << 'callbacks') && params.shift if around_callback?
50
- names += params.map{|name| "name_arg.call(:#{name})"}
63
+ names += params.map{|name| "name_proc.call(:#{name})"}
51
64
  return names.join(', ') if names.any?
52
65
  end
53
66
 
@@ -67,7 +80,7 @@ module Workflow
67
80
  end
68
81
 
69
82
  def procedure_string
70
- '&inner_procedure'
83
+ '&raw_proc'
71
84
  end
72
85
 
73
86
  def name_params
@@ -93,10 +106,11 @@ module Workflow
93
106
  end
94
107
 
95
108
  def parameters
96
- inner_procedure.parameters
109
+ raw_proc.parameters
97
110
  end
111
+
98
112
  def arity
99
- inner_procedure.arity
113
+ raw_proc.arity
100
114
  end
101
115
  end
102
116
  end
@@ -40,7 +40,7 @@ module Workflow
40
40
  end
41
41
 
42
42
  def values
43
- [from, to, event, event_args]
43
+ [from, to, event, event_args.dup, attributes.dup]
44
44
  end
45
45
 
46
46
  def respond_to?(method)
@@ -1,3 +1,3 @@
1
1
  module Workflow
2
- VERSION = "1.4.2.4"
2
+ VERSION = "1.4.4.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2.4
4
+ version: 1.4.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Gannon
@@ -209,6 +209,7 @@ files:
209
209
  - Rakefile
210
210
  - asdf
211
211
  - bin/console
212
+ - bin/deploy
212
213
  - bin/setup
213
214
  - gemfiles/Gemfile.rails-3.x
214
215
  - gemfiles/Gemfile.rails-4.0
@@ -220,6 +221,7 @@ files:
220
221
  - lib/workflow/adapters/remodel.rb
221
222
  - lib/workflow/callbacks.rb
222
223
  - lib/workflow/callbacks/callback.rb
224
+ - lib/workflow/callbacks/transition_callback_method_wrapper.rb
223
225
  - lib/workflow/callbacks/transition_callback_wrapper.rb
224
226
  - lib/workflow/configuration.rb
225
227
  - lib/workflow/draw.rb