activeinteractor 0.1.2 → 0.1.3

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
  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: []