activeinteractor 0.1.2 → 0.1.3

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
  SHA256:
3
- metadata.gz: e933d8615e2b55bf47049e291b801193e2341b03e3c0a29bb8d8f7c8166adee3
4
- data.tar.gz: afc759ee08f37bbbba50e2ac6c1508afb0d303c0f37ca5cdfcf75d6347e210b0
3
+ metadata.gz: 5ce2748cbf2a6f2584dbcb73cfce3347d2bd9447e7f02af34bb99d488c50e117
4
+ data.tar.gz: c5c088b60da0c26ddab97fa8f9c033375e6ef95e2aff17363c3f828b2df433dc
5
5
  SHA512:
6
- metadata.gz: 8edc74485608e067bb6e9e9df3a19d9c0651df4351c9e56239b41ce1fb39fa4d7595e08366799fcbcfa79390e0fe1a1f1b0a652e01f8855905d93dcc53d05b69
7
- data.tar.gz: 0d8b82c2ebfce20b413a4563eb0244081b1ca3910186de9ad9880cc246408df68e282ef0ec21adb4f89eda7947fe79c62555f1c24c8795a08dff15bd7dec621d
6
+ metadata.gz: aa6e94e75c3470d0e3807c0caf4802ec543613d731bde0c8d693943ebe594ec91538a28bc29fbb43ed738da9d6705c97211301bb4294e902e2c43fa50f543d05
7
+ data.tar.gz: 437b0c0e527018c101610d2f7731130cfd8f2df62627242a6ec6ed24430427473501c72429ef53378892ce6155704bc7b0665d243c8fe4a49d1d3dad27fb0c13
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning].
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [v0.1.3] - 2019-04-01
11
+
12
+ ### Added
13
+
14
+ - #25: Implement `each_perform` callbacks on organizers
15
+
10
16
  ## [v0.1.2] - 2019-04-01
11
17
 
12
18
  ### Added
@@ -27,6 +33,7 @@ and this project adheres to [Semantic Versioning].
27
33
  [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
28
34
  [Semantic Versioning]: https://semver.org/spec/v2.0.0.html
29
35
 
30
- [Unreleased]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.2...HEAD
36
+ [Unreleased]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.3..HEAD
37
+ [v0.1.3]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.2...v0.1.3
31
38
  [v0.1.2]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.1...v0.1.2
32
39
  [v0.1.1]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.0...v0.1.1
data/README.md CHANGED
@@ -460,6 +460,127 @@ context.rollback!
460
460
  "Done"
461
461
  ```
462
462
 
463
+ We can do worker before `perform` is invoked on each interactor in an [Organizer](#organizers) with the `before_each_perform` method:
464
+
465
+ ```ruby
466
+ class MyInteractor1 < ActiveInteractor::Base
467
+ before_perform :print_name
468
+
469
+ def perform
470
+ puts 'MyInteractor1'
471
+ end
472
+ end
473
+
474
+ class MyInteractor2 < ActiveInteractor::Base
475
+ before_perform :print_name
476
+
477
+ def perform
478
+ puts 'MyInteractor2'
479
+ end
480
+ end
481
+
482
+ class MyOrganizer < ActiveInteractor::Organizer
483
+ before_each_perform :print_start
484
+
485
+ organized MyInteractor1, MyInteractor2
486
+
487
+ private
488
+
489
+ def print_start
490
+ puts "Start"
491
+ end
492
+ end
493
+
494
+ MyOrganizer.perform(name: 'Aaron')
495
+ "Start"
496
+ "MyInteractor1"
497
+ "Start"
498
+ "MyInteractor2"
499
+ #=> <MyOrganizer::Context name='Aaron'>
500
+ ```
501
+
502
+ We can do worker around `perform` is invokation on each interactor in an [Organizer](#organizers) with the `around_each_perform` method:
503
+
504
+ ```ruby
505
+ class MyInteractor1 < ActiveInteractor::Base
506
+ before_perform :print_name
507
+
508
+ def perform
509
+ puts 'MyInteractor1'
510
+ end
511
+ end
512
+
513
+ class MyInteractor2 < ActiveInteractor::Base
514
+ before_perform :print_name
515
+
516
+ def perform
517
+ puts 'MyInteractor2'
518
+ end
519
+ end
520
+
521
+ class MyOrganizer < ActiveInteractor::Organizer
522
+ around_each_perform :print_time
523
+
524
+ organized MyInteractor1, MyInteractor2
525
+
526
+ private
527
+
528
+ def print_time
529
+ puts Time.now.utc
530
+ yield
531
+ puts Time.now.utc
532
+ end
533
+ end
534
+
535
+ MyOrganizer.perform(name: 'Aaron')
536
+ "2019-04-01 00:00:00 UTC"
537
+ "MyInteractor1"
538
+ "2019-04-01 00:00:01 UTC"
539
+ "2019-04-01 00:00:02 UTC"
540
+ "MyInteractor2"
541
+ "2019-04-01 00:00:03 UTC"
542
+ #=> <MyOrganizer::Context name='Aaron'>
543
+ ```
544
+
545
+ We can do worker after `perform` is invoked on each interactor in an [Organizer](#organizers) with the `after_each_perform` method:
546
+
547
+ ```ruby
548
+ class MyInteractor1 < ActiveInteractor::Base
549
+ before_perform :print_name
550
+
551
+ def perform
552
+ puts 'MyInteractor1'
553
+ end
554
+ end
555
+
556
+ class MyInteractor2 < ActiveInteractor::Base
557
+ before_perform :print_name
558
+
559
+ def perform
560
+ puts 'MyInteractor2'
561
+ end
562
+ end
563
+
564
+ class MyOrganizer < ActiveInteractor::Organizer
565
+ after_each_perform :print_done
566
+
567
+ organized MyInteractor1, MyInteractor2
568
+
569
+ private
570
+
571
+ def print_done
572
+ puts "done"
573
+ end
574
+ end
575
+
576
+ MyOrganizer.perform(name: 'Aaron')
577
+ "MyInteractor1"
578
+ "Done"
579
+ "MyInteractor2"
580
+ "Done"
581
+ #=> <MyOrganizer::Context name='Aaron'>
582
+ ```
583
+
463
584
  ### Using Interactors
464
585
 
465
586
  Most of the time, your application will use its interactors from its controllers. The following controller:
@@ -5,15 +5,15 @@ module ActiveInteractor
5
5
  #
6
6
  # @author Aaron Allen <hello@aaronmallen.me>
7
7
  # @since 0.0.1
8
- # @version 0.1
8
+ # @version 0.2
9
9
  #
10
10
  # @!attribute [rw] logger
11
11
  # @return [Logger] an instance of Logger
12
+ # @!attribute [rw] dir_name
13
+ # @return [String] The directory name interactors are generated in
12
14
  class Configuration
13
15
  # The default configuration options for {Configuration}
14
16
  # @return [Hash{Symbol => *}]
15
- # * :logger - The Logger instance to use for logging
16
- # * :dir_name - The directory interactors are generated in
17
17
  DEFAULTS = {
18
18
  logger: Logger.new(STDOUT),
19
19
  dir_name: 'interactors'
@@ -26,6 +26,7 @@ module ActiveInteractor
26
26
  # configuration with.
27
27
  # @option options [Logger] :logger the logger ActiveInteractor should
28
28
  # use for logging
29
+ # @option options [String] :dir_name he directory name interactors are generated in
29
30
  # @return [ActiveInteractor::Configuration] a new instance of {Configuration}
30
31
  def initialize(options = {})
31
32
  options = DEFAULTS.merge(options.dup || {}).slice(*DEFAULTS.keys)
@@ -39,7 +39,7 @@ module ActiveInteractor
39
39
  # end
40
40
  # end
41
41
  #
42
- # context = MyInteractor.new(name: 'Bob').context
42
+ # context = MyInteractor.perform(name: 'Bob')
43
43
  # #=> <MyInteractor::Context name='Bob'>
44
44
  #
45
45
  # context.valid?
@@ -186,7 +186,7 @@ module ActiveInteractor
186
186
  # end
187
187
  # end
188
188
  #
189
- # context = MyInteractor.new(name: 'Bob').context
189
+ # context = MyInteractor.perform(name: 'Bob')
190
190
  # #=> <MyInteractor::Context name='Bob'>
191
191
  #
192
192
  # context.valid?
@@ -2,6 +2,11 @@
2
2
 
3
3
  module ActiveInteractor
4
4
  module Interactor
5
+ # Provides worker methods to included classes
6
+ #
7
+ # @author Aaron Allen <hello@aaronmallen.me>
8
+ # @since 0.0.2
9
+ # @version 0.2
5
10
  module Execution
6
11
  extend ActiveSupport::Concern
7
12
 
@@ -2,6 +2,12 @@
2
2
 
3
3
  module ActiveInteractor
4
4
  module Interactor
5
+ # A worker class responsible for thread safe execution
6
+ # of interactor {.perform} methods.
7
+ #
8
+ # @author Aaron Allen <hello@aaronmallen.me>
9
+ # @since 0.0.2
10
+ # @version 0.1
5
11
  class Worker
6
12
  delegate :run_callbacks, to: :interactor
7
13
 
@@ -36,6 +42,8 @@ module ActiveInteractor
36
42
  end
37
43
 
38
44
  # Calls {Interactor#rollback} with callbacks
45
+ # @return [Boolean] `true` if rolled back successfully or `false` if already
46
+ # rolled back
39
47
  def execute_rollback
40
48
  run_callbacks :rollback do
41
49
  interactor.rollback
@@ -5,12 +5,144 @@ module ActiveInteractor
5
5
  #
6
6
  # @author Aaron Allen <hello@aaronmallen.me>
7
7
  # @since 0.0.1
8
- # @version 0.1
8
+ # @version 0.3
9
9
  class Organizer < ActiveInteractor::Base
10
+ define_callbacks :each_perform
11
+
10
12
  class << self
13
+ # Define a callback to call after each organized interactor's
14
+ # {ActiveInteractor::Base.perform} has been invoked
15
+ #
16
+ # @example
17
+ # class MyInteractor1 < ActiveInteractor::Base
18
+ # before_perform :print_name
19
+ #
20
+ # def perform
21
+ # puts 'MyInteractor1'
22
+ # end
23
+ # end
24
+ #
25
+ # class MyInteractor2 < ActiveInteractor::Base
26
+ # before_perform :print_name
27
+ #
28
+ # def perform
29
+ # puts 'MyInteractor2'
30
+ # end
31
+ # end
32
+ #
33
+ # class MyOrganizer < ActiveInteractor::Organizer
34
+ # after_each_perform :print_done
35
+ #
36
+ # organized MyInteractor1, MyInteractor2
37
+ #
38
+ # private
39
+ #
40
+ # def print_done
41
+ # puts "done"
42
+ # end
43
+ # end
44
+ #
45
+ # MyOrganizer.perform(name: 'Aaron')
46
+ # "MyInteractor1"
47
+ # "Done"
48
+ # "MyInteractor2"
49
+ # "Done"
50
+ # #=> <MyOrganizer::Context name='Aaron'>
51
+ def after_each_perform(*filters, &block)
52
+ set_callback(:each_perform, :after, *filters, &block)
53
+ end
54
+
55
+ # Define a callback to call around each organized interactor's
56
+ # {ActiveInteractor::Base.perform} has been invokation
57
+ #
58
+ # @example
59
+ # class MyInteractor1 < ActiveInteractor::Base
60
+ # before_perform :print_name
61
+ #
62
+ # def perform
63
+ # puts 'MyInteractor1'
64
+ # end
65
+ # end
66
+ #
67
+ # class MyInteractor2 < ActiveInteractor::Base
68
+ # before_perform :print_name
69
+ #
70
+ # def perform
71
+ # puts 'MyInteractor2'
72
+ # end
73
+ # end
74
+ #
75
+ # class MyOrganizer < ActiveInteractor::Organizer
76
+ # around_each_perform :print_time
77
+ #
78
+ # organized MyInteractor1, MyInteractor2
79
+ #
80
+ # private
81
+ #
82
+ # def print_time
83
+ # puts Time.now.utc
84
+ # yield
85
+ # puts Time.now.utc
86
+ # end
87
+ # end
88
+ #
89
+ # MyOrganizer.perform(name: 'Aaron')
90
+ # "2019-04-01 00:00:00 UTC"
91
+ # "MyInteractor1"
92
+ # "2019-04-01 00:00:01 UTC"
93
+ # "2019-04-01 00:00:02 UTC"
94
+ # "MyInteractor2"
95
+ # "2019-04-01 00:00:03 UTC"
96
+ # #=> <MyOrganizer::Context name='Aaron'>
97
+ def around_each_perform(*filters, &block)
98
+ set_callback(:each_perform, :around, *filters, &block)
99
+ end
100
+
101
+ # Define a callback to call before each organized interactor's
102
+ # {ActiveInteractor::Base.perform} has been invoked
103
+ #
104
+ # @example
105
+ # class MyInteractor1 < ActiveInteractor::Base
106
+ # before_perform :print_name
107
+ #
108
+ # def perform
109
+ # puts 'MyInteractor1'
110
+ # end
111
+ # end
112
+ #
113
+ # class MyInteractor2 < ActiveInteractor::Base
114
+ # before_perform :print_name
115
+ #
116
+ # def perform
117
+ # puts 'MyInteractor2'
118
+ # end
119
+ # end
120
+ #
121
+ # class MyOrganizer < ActiveInteractor::Organizer
122
+ # before_each_perform :print_start
123
+ #
124
+ # organized MyInteractor1, MyInteractor2
125
+ #
126
+ # private
127
+ #
128
+ # def print_start
129
+ # puts "Start"
130
+ # end
131
+ # end
132
+ #
133
+ # MyOrganizer.perform(name: 'Aaron')
134
+ # "Start"
135
+ # "MyInteractor1"
136
+ # "Start"
137
+ # "MyInteractor2"
138
+ # #=> <MyOrganizer::Context name='Aaron'>
139
+ def before_each_perform(*filters, &block)
140
+ set_callback(:each_perform, :before, *filters, &block)
141
+ end
142
+
11
143
  # Declare Interactors to be invoked as part of the
12
144
  # organizer's invocation. These interactors are invoked in
13
- # the order in which they are declared.
145
+ # the order in which they are declared
14
146
  #
15
147
  # @example
16
148
  # class MyFirstOrganizer < ActiveInteractor::Organizer
@@ -26,8 +158,8 @@ module ActiveInteractor
26
158
  @organized = interactors.flatten
27
159
  end
28
160
 
29
- # An Array of declared Interactors to be invoked.
30
- # @private
161
+ # An Array of declared Interactors to be invoked
162
+ # @return [Array<ActiveInteractor::Base] the organized interactors
31
163
  def organized
32
164
  @organized ||= []
33
165
  end
@@ -38,9 +170,11 @@ module ActiveInteractor
38
170
  # in favor of this default implementation.
39
171
  def perform
40
172
  self.class.organized.each do |interactor|
41
- self.context = interactor.new(context)
42
- .tap(&:skip_clean_context!)
43
- .execute_perform!
173
+ run_callbacks :each_perform do
174
+ self.context = interactor.new(context)
175
+ .tap(&:skip_clean_context!)
176
+ .execute_perform!
177
+ end
44
178
  end
45
179
  end
46
180
  end
@@ -3,5 +3,5 @@
3
3
  module ActiveInteractor
4
4
  # The ActiveInteractor gem version
5
5
  # @return [String] the gem version
6
- VERSION = '0.1.2'
6
+ VERSION = '0.1.3'
7
7
  end
@@ -26,7 +26,7 @@ require 'active_interactor/version'
26
26
  #
27
27
  # @author Aaron Allen <hello@aaronmallen.me>
28
28
  # @since 0.0.1
29
- # @version 0.1
29
+ # @version 0.2
30
30
  module ActiveInteractor
31
31
  extend ActiveSupport::Autoload
32
32
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeinteractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Allen
@@ -244,10 +244,10 @@ licenses:
244
244
  - MIT
245
245
  metadata:
246
246
  bug_tracker_uri: https://github.com/aaronmallen/activeinteractor/issues
247
- changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v0.1.2/CHANGELOG.md
248
- documentation_uri: https://www.rubydoc.info/gems/activeinteractor/0.1.2
247
+ changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v0.1.3/CHANGELOG.md
248
+ documentation_uri: https://www.rubydoc.info/gems/activeinteractor/0.1.3
249
249
  hompage_uri: https://github.com/aaronmallen/activeinteractor
250
- source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v0.1.2
250
+ source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v0.1.3
251
251
  wiki_uri: https://github.com/aaronmallen/activeinteractor/wiki
252
252
  post_install_message:
253
253
  rdoc_options: []