activeinteractor 1.2.2 → 2.0.0.alpha.1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/LICENSE +1 -1
- data/README.md +4 -64
- data/lib/active_interactor/base.rb +77 -29
- data/lib/active_interactor/errors.rb +12 -0
- data/lib/active_interactor/result.rb +73 -0
- data/lib/active_interactor.rb +3 -101
- data/sig/active_interactor.rbs +3 -0
- metadata +23 -86
- data/.yardopts +0 -12
- data/lib/active_interactor/config.rb +0 -60
- data/lib/active_interactor/configurable.rb +0 -53
- data/lib/active_interactor/context/attributes.rb +0 -179
- data/lib/active_interactor/context/base.rb +0 -333
- data/lib/active_interactor/context/errors.rb +0 -57
- data/lib/active_interactor/context/loader.rb +0 -50
- data/lib/active_interactor/context/status.rb +0 -106
- data/lib/active_interactor/error.rb +0 -46
- data/lib/active_interactor/interactor/callbacks.rb +0 -293
- data/lib/active_interactor/interactor/context.rb +0 -378
- data/lib/active_interactor/interactor/perform.rb +0 -260
- data/lib/active_interactor/interactor/worker.rb +0 -120
- data/lib/active_interactor/models.rb +0 -50
- data/lib/active_interactor/organizer/base.rb +0 -18
- data/lib/active_interactor/organizer/callbacks.rb +0 -275
- data/lib/active_interactor/organizer/interactor_interface.rb +0 -127
- data/lib/active_interactor/organizer/interactor_interface_collection.rb +0 -62
- data/lib/active_interactor/organizer/organize.rb +0 -67
- data/lib/active_interactor/organizer/perform.rb +0 -112
- data/lib/active_interactor/rails/orm/active_record.rb +0 -5
- data/lib/active_interactor/rails/orm/dynamoid.rb +0 -5
- data/lib/active_interactor/rails/orm/mongoid.rb +0 -5
- data/lib/active_interactor/rails/railtie.rb +0 -21
- data/lib/active_interactor/rails.rb +0 -4
- data/lib/active_interactor/version.rb +0 -45
- data/lib/rails/generators/active_interactor/application_context_generator.rb +0 -21
- data/lib/rails/generators/active_interactor/application_interactor_generator.rb +0 -21
- data/lib/rails/generators/active_interactor/application_organizer_generator.rb +0 -21
- data/lib/rails/generators/active_interactor/base.rb +0 -29
- data/lib/rails/generators/active_interactor/generator.rb +0 -21
- data/lib/rails/generators/active_interactor/install_generator.rb +0 -16
- data/lib/rails/generators/active_interactor.rb +0 -5
- data/lib/rails/generators/interactor/context/rspec_generator.rb +0 -17
- data/lib/rails/generators/interactor/context/test_unit_generator.rb +0 -17
- data/lib/rails/generators/interactor/context_generator.rb +0 -22
- data/lib/rails/generators/interactor/generates_context.rb +0 -28
- data/lib/rails/generators/interactor/interactor_generator.rb +0 -25
- data/lib/rails/generators/interactor/organizer_generator.rb +0 -39
- data/lib/rails/generators/interactor/rspec_generator.rb +0 -15
- data/lib/rails/generators/interactor/test_unit_generator.rb +0 -15
- data/lib/rails/generators/templates/active_interactor.erb +0 -17
- data/lib/rails/generators/templates/application_context.rb +0 -4
- data/lib/rails/generators/templates/application_interactor.rb +0 -4
- data/lib/rails/generators/templates/application_organizer.rb +0 -4
- data/lib/rails/generators/templates/context.erb +0 -7
- data/lib/rails/generators/templates/context_spec.erb +0 -7
- data/lib/rails/generators/templates/context_test_unit.erb +0 -9
- data/lib/rails/generators/templates/interactor.erb +0 -15
- data/lib/rails/generators/templates/interactor_spec.erb +0 -7
- data/lib/rails/generators/templates/interactor_test_unit.erb +0 -9
- data/lib/rails/generators/templates/organizer.erb +0 -13
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveInteractor
|
4
|
-
module Context
|
5
|
-
# Context status methods. Because {Status} is a module classes should include {Status} rather than inherit from it.
|
6
|
-
#
|
7
|
-
# @author Aaron Allen <hello@aaronmallen.me>
|
8
|
-
# @since 1.0.0
|
9
|
-
module Status
|
10
|
-
# Add an instance of {ActiveInteractor::Base interactor} to the list of {ActiveInteractor::Base interactors}
|
11
|
-
# called on the {Base context}. This list is used when {#rollback!} is called on a {Base context} instance.
|
12
|
-
#
|
13
|
-
# @since 0.1.0
|
14
|
-
#
|
15
|
-
# @param interactor [Class] an {ActiveInteractor::Base interactor} instance
|
16
|
-
# @return [Array<Class>] the list of called {ActiveInteractor::Base interactors}
|
17
|
-
def called!(interactor)
|
18
|
-
_called << interactor
|
19
|
-
end
|
20
|
-
|
21
|
-
# Fail the {Base context} instance. Failing an instance raises an error that may be rescued by the calling
|
22
|
-
# {ActiveInteractor::Base interactor}. The instance is also flagged as having failed.
|
23
|
-
#
|
24
|
-
# @since 0.1.0
|
25
|
-
#
|
26
|
-
# @example Fail an interactor context
|
27
|
-
# class MyInteractor < ActiveInteractor::Base
|
28
|
-
# def perform
|
29
|
-
# context.fail!
|
30
|
-
# end
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# MyInteractor.perform!
|
34
|
-
# ActiveInteractor::Error::ContextFailure "<#MyInteractor::Context>"
|
35
|
-
#
|
36
|
-
# @param errors [ActiveModel::Errors, String] error messages for the failure
|
37
|
-
# @see https://api.rubyonrails.org/classes/ActiveModel/Errors.html ActiveModel::Errors
|
38
|
-
# @raise [Error::ContextFailure]
|
39
|
-
def fail!(errors = nil)
|
40
|
-
handle_errors(errors) if errors
|
41
|
-
@_failed = true
|
42
|
-
resolve
|
43
|
-
raise ActiveInteractor::Error::ContextFailure, self
|
44
|
-
end
|
45
|
-
|
46
|
-
# Whether the {Base context} instance has {#fail! failed}. By default, a new instance is successful and only
|
47
|
-
# changes when explicitly {#fail! failed}.
|
48
|
-
#
|
49
|
-
# @since 0.1.0
|
50
|
-
# @note The {#failure?} method is the inverse of the {#success?} method
|
51
|
-
#
|
52
|
-
# @example Check if a context has failed
|
53
|
-
# result = MyInteractor.perform
|
54
|
-
# result.failure?
|
55
|
-
# #=> false
|
56
|
-
#
|
57
|
-
# @return [Boolean] `false` by default or `true` if {#fail! failed}.
|
58
|
-
def failure?
|
59
|
-
@_failed || false
|
60
|
-
end
|
61
|
-
alias fail? failure?
|
62
|
-
|
63
|
-
# Resolve an instance of {Base context}. Called when an interactor
|
64
|
-
# is finished with it's context.
|
65
|
-
#
|
66
|
-
# @since 1.0.3
|
67
|
-
# @return [self] the instance of {Base context}
|
68
|
-
def resolve
|
69
|
-
resolve_errors
|
70
|
-
self
|
71
|
-
end
|
72
|
-
|
73
|
-
# {#rollback! Rollback} an instance of {Base context}. Any {ActiveInteractor::Base interactors} the instance has
|
74
|
-
# been passed via the {#called!} method are asked to roll themselves back by invoking their
|
75
|
-
# {Interactor::Perform#rollback #rollback} methods. The instance is also flagged as rolled back.
|
76
|
-
#
|
77
|
-
# @since 0.1.0
|
78
|
-
#
|
79
|
-
# @return [Boolean] `true` if {#rollback! rolled back} successfully or `false` if already
|
80
|
-
# {#rollback! rolled back}
|
81
|
-
def rollback!
|
82
|
-
return false if @_rolled_back
|
83
|
-
|
84
|
-
_called.reverse_each(&:rollback)
|
85
|
-
@_rolled_back = true
|
86
|
-
end
|
87
|
-
|
88
|
-
# Whether the {Base context} instance is successful. By default, a new instance is successful and only changes
|
89
|
-
# when explicitly {#fail! failed}.
|
90
|
-
#
|
91
|
-
# @since 0.1.0
|
92
|
-
# @note The {#success?} method is the inverse of the {#failure?} method
|
93
|
-
#
|
94
|
-
# @example Check if a context has failed
|
95
|
-
# result = MyInteractor.perform
|
96
|
-
# result.success?
|
97
|
-
# #=> true
|
98
|
-
#
|
99
|
-
# @return [Boolean] `true` by default or `false` if {#fail! failed}
|
100
|
-
def success?
|
101
|
-
!failure?
|
102
|
-
end
|
103
|
-
alias successful? success?
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveInteractor
|
4
|
-
# ActiveInteractor errors
|
5
|
-
#
|
6
|
-
# @author Aaron Allen <hello@aaronmallen.me>
|
7
|
-
# @since 0.1.5
|
8
|
-
module Error
|
9
|
-
# Raised when an {Base interactor} {Context::Base context} {Context::Status#fail! fails}.
|
10
|
-
#
|
11
|
-
# @!attribute [r] context
|
12
|
-
# An instance of {Context::Base context} used for debugging.
|
13
|
-
#
|
14
|
-
# @return [Context::Base] an instance of {Context::Base}
|
15
|
-
class ContextFailure < StandardError
|
16
|
-
attr_reader :context
|
17
|
-
|
18
|
-
# Initialize a new instance of {ContextFailure}
|
19
|
-
#
|
20
|
-
# @param context [Class, nil] an instance of {Context::Base context}
|
21
|
-
# @return [ContextFailure] a new instance of {ContextFailure}
|
22
|
-
def initialize(context = nil)
|
23
|
-
@context = context
|
24
|
-
context_class_name = context&.class&.name || 'Context'
|
25
|
-
super("#{context_class_name} failed!")
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Raised when an invalid {Context::Base context} class is assigned to an {Base interactor}.
|
30
|
-
#
|
31
|
-
# @since 1.0.0
|
32
|
-
#
|
33
|
-
# @!attribute [r] class_name
|
34
|
-
# The class name of the {Context::Base context} used for debugging.
|
35
|
-
#
|
36
|
-
# @return [String|nil] the class name of the {Context::Base context}
|
37
|
-
class InvalidContextClass < StandardError
|
38
|
-
attr_reader :class_name
|
39
|
-
|
40
|
-
def initialize(class_name = nil)
|
41
|
-
@class_name = class_name
|
42
|
-
super("invalid context class #{class_name}")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,293 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveInteractor
|
4
|
-
module Interactor
|
5
|
-
# Interactor callback methods. Because {Callbacks} is a module classes should include {Callbacks} rather than
|
6
|
-
# inherit from it.
|
7
|
-
#
|
8
|
-
# @author Aaron Allen <hello@aaronmallen.me>
|
9
|
-
# @since 0.1.0
|
10
|
-
# @see https://github.com/aaronmallen/activeinteractor/wiki/Callbacks Callbacks
|
11
|
-
# @see https://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html ActiveSupport::Callbacks
|
12
|
-
module Callbacks
|
13
|
-
# Interactor callback class methods. Because {ClassMethods} is a module classes should extend {ClassMethods}
|
14
|
-
# rather than inherit from it.
|
15
|
-
#
|
16
|
-
# @author Aaron Allen
|
17
|
-
# @since 0.1.0
|
18
|
-
module ClassMethods
|
19
|
-
# Define a callback to call after validation has been run on an {Base interactor} instance's
|
20
|
-
# {ActiveInteractor::Context::Base context} instance.
|
21
|
-
#
|
22
|
-
# @example
|
23
|
-
# class MyInteractor < ActiveInteractor::Base
|
24
|
-
# after_context_validation :ensure_name_is_aaron
|
25
|
-
# context_validates :name, presence: true
|
26
|
-
#
|
27
|
-
# private
|
28
|
-
#
|
29
|
-
# def ensure_name_is_aaron
|
30
|
-
# context.name = 'Aaron'
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# result = MyInteractor.perform(name: 'Bob')
|
35
|
-
# result.name
|
36
|
-
# #=> 'Aaron'
|
37
|
-
#
|
38
|
-
# result = MyInteractor.perform({ name: 'Bob' }, { validate: false })
|
39
|
-
# result.name
|
40
|
-
# #=> 'Bob'
|
41
|
-
def after_context_validation(*args, &block)
|
42
|
-
options = normalize_options(args.extract_options!.dup.merge(prepend: true))
|
43
|
-
set_callback(:validation, :after, *args, options, &block)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Define a callback to call after {Interactor::Perform#perform #perform} has been called on an
|
47
|
-
# {Base interactor} instance.
|
48
|
-
#
|
49
|
-
# @example
|
50
|
-
# class MyInteractor < ActiveInteractor::Base
|
51
|
-
# after_perform :print_done
|
52
|
-
#
|
53
|
-
# def perform
|
54
|
-
# puts 'Performing'
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# private
|
58
|
-
#
|
59
|
-
# def print_done
|
60
|
-
# puts 'Done'
|
61
|
-
# end
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# MyInteractor.perform
|
65
|
-
# "Performing"
|
66
|
-
# "Done"
|
67
|
-
# #=> <#MyInteractor::Context>
|
68
|
-
def after_perform(*filters, &block)
|
69
|
-
set_callback(:perform, :after, *filters, &block)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Define a callback to call after {Interactor::Perform#rollback #rollback} has been called on an
|
73
|
-
# {Base interactor} instance.
|
74
|
-
#
|
75
|
-
# @example
|
76
|
-
# class MyInteractor < ActiveInteractor::Base
|
77
|
-
# after_rollback :print_done
|
78
|
-
#
|
79
|
-
# def perform
|
80
|
-
# context.fail!
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# def rollback
|
84
|
-
# puts 'Rolling Back'
|
85
|
-
# end
|
86
|
-
#
|
87
|
-
# private
|
88
|
-
#
|
89
|
-
# def print_done
|
90
|
-
# puts 'Done'
|
91
|
-
# end
|
92
|
-
# end
|
93
|
-
#
|
94
|
-
# MyInteractor.perform
|
95
|
-
# "Rolling Back"
|
96
|
-
# "Done"
|
97
|
-
# #=> <MyInteractor::Context>
|
98
|
-
def after_rollback(*filters, &block)
|
99
|
-
set_callback(:rollback, :after, *filters, &block)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Define a callback to call around {Interactor::Perform#perform #perform} invokation on an {Base interactor}
|
103
|
-
# instance.
|
104
|
-
#
|
105
|
-
# @example
|
106
|
-
# class MyInteractor < ActiveInteractor::Base
|
107
|
-
# around_perform :track_time
|
108
|
-
#
|
109
|
-
# def perform
|
110
|
-
# sleep(1)
|
111
|
-
# end
|
112
|
-
#
|
113
|
-
# private
|
114
|
-
#
|
115
|
-
# def track_time
|
116
|
-
# context.start_time = Time.now.utc
|
117
|
-
# yield
|
118
|
-
# context.end_time = Time.now.utc
|
119
|
-
# end
|
120
|
-
# end
|
121
|
-
#
|
122
|
-
# result = MyInteractor.perform
|
123
|
-
# result.start_time
|
124
|
-
# #=> 2019-01-01 00:00:00 UTC
|
125
|
-
#
|
126
|
-
# result.end_time
|
127
|
-
# #=> 2019-01-01 00:00:01 UTC
|
128
|
-
def around_perform(*filters, &block)
|
129
|
-
set_callback(:perform, :around, *filters, &block)
|
130
|
-
end
|
131
|
-
|
132
|
-
# Define a callback to call around {Interactor::Perform#rollback #rollback} invokation on an {Base interactor}
|
133
|
-
# instance.
|
134
|
-
#
|
135
|
-
# @example
|
136
|
-
# class MyInteractor < ActiveInteractor::Base
|
137
|
-
# around_rollback :track_time
|
138
|
-
#
|
139
|
-
# def perform
|
140
|
-
# context.fail!
|
141
|
-
# end
|
142
|
-
#
|
143
|
-
# def rollback
|
144
|
-
# sleep(1)
|
145
|
-
# end
|
146
|
-
#
|
147
|
-
# private
|
148
|
-
#
|
149
|
-
# def track_time
|
150
|
-
# context.start_time = Time.now.utc
|
151
|
-
# yield
|
152
|
-
# context.end_time = Time.now.utc
|
153
|
-
# end
|
154
|
-
# end
|
155
|
-
#
|
156
|
-
# result = MyInteractor.perform
|
157
|
-
# result.start_time
|
158
|
-
# #=> 2019-01-01 00:00:00 UTC
|
159
|
-
#
|
160
|
-
# result.end_time
|
161
|
-
# #=> 2019-01-01 00:00:01 UTC
|
162
|
-
def around_rollback(*filters, &block)
|
163
|
-
set_callback(:rollback, :around, *filters, &block)
|
164
|
-
end
|
165
|
-
|
166
|
-
# Define a callback to call before validation has been run on an {Base interactor} instance's
|
167
|
-
# {ActiveInteractor::Context::Base context} instance.
|
168
|
-
#
|
169
|
-
# @example
|
170
|
-
# class MyInteractor < ActiveInteractor::Base
|
171
|
-
# before_context_validation :ensure_name_is_aaron
|
172
|
-
# context_validates :name, inclusion: { in: %w[Aaron] }
|
173
|
-
#
|
174
|
-
# private
|
175
|
-
#
|
176
|
-
# def ensure_name_is_aaron
|
177
|
-
# context.name = 'Aaron'
|
178
|
-
# end
|
179
|
-
# end
|
180
|
-
#
|
181
|
-
# result = MyInteractor.perform(name: 'Bob')
|
182
|
-
# result.successful?
|
183
|
-
# #=> true
|
184
|
-
#
|
185
|
-
# result.name
|
186
|
-
# #=> 'Aaron'
|
187
|
-
#
|
188
|
-
# result = MyInteractor.perform({ name: 'Bob' }, { validate: false })
|
189
|
-
# result.name
|
190
|
-
# #=> 'Bob'
|
191
|
-
def before_context_validation(*args, &block)
|
192
|
-
options = normalize_options(args.extract_options!.dup)
|
193
|
-
set_callback(:validation, :before, *args, options, &block)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Define a callback to call before {Interactor::Perform#perform #perform} has been called on an
|
197
|
-
# {Base interactor} instance
|
198
|
-
#
|
199
|
-
# @example
|
200
|
-
# class MyInteractor < ActiveInteractor::Base
|
201
|
-
# before_perform :print_starting
|
202
|
-
#
|
203
|
-
# def perform
|
204
|
-
# puts 'Performing'
|
205
|
-
# end
|
206
|
-
#
|
207
|
-
# private
|
208
|
-
#
|
209
|
-
# def print_starting
|
210
|
-
# puts 'Starting'
|
211
|
-
# end
|
212
|
-
# end
|
213
|
-
#
|
214
|
-
# MyInteractor.perform
|
215
|
-
# "Starting"
|
216
|
-
# "Performing"
|
217
|
-
# #=> <#MyInteractor::Context>
|
218
|
-
def before_perform(*filters, &block)
|
219
|
-
set_callback(:perform, :before, *filters, &block)
|
220
|
-
end
|
221
|
-
|
222
|
-
# Define a callback to call before {Interactor::Perform#rollback #rollback} has been called on an
|
223
|
-
# {Base interactor} instance.
|
224
|
-
#
|
225
|
-
# @example
|
226
|
-
# class MyInteractor < ActiveInteractor::Base
|
227
|
-
# before_rollback :print_starting
|
228
|
-
#
|
229
|
-
# def perform
|
230
|
-
# context.fail!
|
231
|
-
# end
|
232
|
-
#
|
233
|
-
# def rollback
|
234
|
-
# puts 'Rolling Back'
|
235
|
-
# end
|
236
|
-
#
|
237
|
-
# private
|
238
|
-
#
|
239
|
-
# def print_starting
|
240
|
-
# puts 'Starting'
|
241
|
-
# end
|
242
|
-
# end
|
243
|
-
#
|
244
|
-
# MyInteractor.perform
|
245
|
-
# "Starting"
|
246
|
-
# "Rolling Back"
|
247
|
-
# #=> <#MyInteractor::Context>
|
248
|
-
def before_rollback(*filters, &block)
|
249
|
-
set_callback(:rollback, :before, *filters, &block)
|
250
|
-
end
|
251
|
-
|
252
|
-
# Set {.after_callbacks_deferred_when_organized} to `true`
|
253
|
-
#
|
254
|
-
# @since v1.2.0
|
255
|
-
#
|
256
|
-
# @example a basic {Base organizer} set to defer 'after' callbacks when organized
|
257
|
-
# class MyOrganizer < ActiveInteractor::Organizer::Base
|
258
|
-
# defer_after_callbacks_when_organized
|
259
|
-
# end
|
260
|
-
def defer_after_callbacks_when_organized
|
261
|
-
self.after_callbacks_deferred_when_organized = true
|
262
|
-
end
|
263
|
-
|
264
|
-
def self.extended(base)
|
265
|
-
base.class_eval do
|
266
|
-
class_attribute :after_callbacks_deferred_when_organized, instance_writer: false, default: false
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
private
|
271
|
-
|
272
|
-
def normalize_options(options)
|
273
|
-
if options.key?(:on)
|
274
|
-
options[:on] = Array(options[:on])
|
275
|
-
options[:if] = Array(options[:if])
|
276
|
-
options[:if].unshift { |o| !(options[:on] & Array(o.validation_context)).empty? }
|
277
|
-
end
|
278
|
-
|
279
|
-
options
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def self.included(base)
|
284
|
-
base.class_eval do
|
285
|
-
define_callbacks :validation,
|
286
|
-
skip_after_callbacks_if_terminated: true,
|
287
|
-
scope: %i[kind name]
|
288
|
-
define_callbacks :perform, :rollback
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|