activeinteractor 0.1.7 → 1.0.0.beta.1

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -1
  3. data/README.md +397 -395
  4. data/lib/active_interactor.rb +12 -30
  5. data/lib/active_interactor/base.rb +18 -8
  6. data/lib/active_interactor/context.rb +4 -181
  7. data/lib/active_interactor/context/attributes.rb +37 -149
  8. data/lib/active_interactor/context/base.rb +141 -0
  9. data/lib/active_interactor/context/loader.rb +45 -0
  10. data/lib/active_interactor/error.rb +22 -15
  11. data/lib/active_interactor/interactor.rb +24 -57
  12. data/lib/active_interactor/interactor/callbacks.rb +64 -76
  13. data/lib/active_interactor/interactor/context.rb +97 -63
  14. data/lib/active_interactor/interactor/worker.rb +22 -65
  15. data/lib/active_interactor/organizer.rb +180 -164
  16. data/lib/active_interactor/version.rb +2 -3
  17. data/lib/rails/generators/active_interactor.rb +2 -37
  18. data/lib/rails/generators/active_interactor/application_interactor_generator.rb +23 -0
  19. data/lib/rails/generators/active_interactor/install_generator.rb +8 -12
  20. data/lib/rails/generators/active_interactor/templates/application_context.rb +4 -0
  21. data/lib/rails/generators/{templates/application_interactor.erb → active_interactor/templates/application_interactor.rb} +0 -0
  22. data/lib/rails/generators/active_interactor/templates/application_organizer.rb +4 -0
  23. data/lib/rails/generators/active_interactor/templates/initializer.erb +5 -0
  24. data/lib/rails/generators/interactor/context/rspec_generator.rb +19 -0
  25. data/lib/rails/generators/interactor/context/templates/rspec.erb +7 -0
  26. data/lib/rails/generators/interactor/context/templates/test_unit.erb +9 -0
  27. data/lib/rails/generators/interactor/context/test_unit_generator.rb +19 -0
  28. data/lib/rails/generators/interactor/context_generator.rb +19 -0
  29. data/lib/rails/generators/interactor/interactor_generator.rb +8 -3
  30. data/lib/rails/generators/interactor/organizer_generator.rb +8 -3
  31. data/lib/rails/generators/interactor/rspec_generator.rb +4 -3
  32. data/lib/rails/generators/interactor/templates/context.erb +4 -0
  33. data/lib/rails/generators/{templates → interactor/templates}/interactor.erb +0 -0
  34. data/lib/rails/generators/{templates → interactor/templates}/organizer.erb +1 -1
  35. data/lib/rails/generators/{templates → interactor/templates}/rspec.erb +0 -0
  36. data/lib/rails/generators/{templates → interactor/templates}/test_unit.erb +0 -0
  37. data/lib/rails/generators/interactor/test_unit_generator.rb +4 -3
  38. data/spec/active_interactor/base_spec.rb +51 -0
  39. data/spec/active_interactor/context/base_spec.rb +229 -0
  40. data/spec/active_interactor/error_spec.rb +43 -0
  41. data/spec/active_interactor/interactor/worker_spec.rb +89 -0
  42. data/spec/active_interactor/organizer_spec.rb +178 -0
  43. data/spec/active_interactor_spec.rb +26 -0
  44. data/spec/integration/basic_callback_integration_spec.rb +355 -0
  45. data/spec/integration/basic_context_integration_spec.rb +73 -0
  46. data/spec/integration/basic_integration_spec.rb +220 -0
  47. data/spec/integration/basic_validations_integration_spec.rb +204 -0
  48. data/spec/spec_helper.rb +44 -0
  49. data/spec/support/helpers/factories.rb +41 -0
  50. data/spec/support/shared_examples/a_class_with_interactor_callback_methods_example.rb +99 -0
  51. data/spec/support/shared_examples/a_class_with_interactor_context_methods_example.rb +58 -0
  52. data/spec/support/shared_examples/a_class_with_interactor_methods_example.rb +21 -0
  53. data/spec/support/shared_examples/a_class_with_organizer_callback_methods_example.rb +39 -0
  54. data/spec/support/spec_helpers.rb +7 -0
  55. metadata +68 -138
  56. data/lib/active_interactor/configuration.rb +0 -38
  57. data/lib/active_interactor/interactor/execution.rb +0 -24
  58. data/lib/rails/generators/templates/initializer.erb +0 -15
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model'
4
+ require 'ostruct'
5
+
6
+ require 'active_interactor/context/attributes'
7
+
8
+ module ActiveInteractor
9
+ module Context
10
+ # The base context class. All interactor contexts should inherit from
11
+ # {Context::Base}.
12
+ # @author Aaron Allen <hello@aaronmallen.me>
13
+ # @since 0.0.1
14
+ class Base < OpenStruct
15
+ include ActiveModel::Validations
16
+ include Attributes
17
+
18
+ # @!method valid?(context = nil)
19
+ # @see
20
+ # https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations.rb#L305
21
+ # ActiveModel::Validations#valid?
22
+
23
+ # @api private
24
+ # Track that an Interactor has been called. The {#called!} method
25
+ # is used by the interactor being invoked with this context. After an
26
+ # interactor is successfully called, the interactor instance is tracked in
27
+ # the context for the purpose of potential future rollback
28
+ # @param interactor [ActiveInteractor::Base] the called interactor
29
+ # @return [Array<ActiveInteractor::Base>] all called interactors
30
+ def called!(interactor)
31
+ _called << interactor
32
+ end
33
+
34
+ # Fail the context instance. Failing a context raises an error
35
+ # that may be rescued by the calling interactor. The context is also flagged
36
+ # as having failed
37
+ #
38
+ # @example Fail an interactor context
39
+ # class MyInteractor < ActiveInteractor::Base
40
+ # def perform
41
+ # context.fail!
42
+ # end
43
+ # end
44
+ #
45
+ # MyInteractor.perform!
46
+ # #=> ActiveInteractor::Error::ContextFailure: <#MyInteractor::Context>
47
+ # @param errors [ActiveModel::Errors|nil] errors to add to the context on failure
48
+ # @see https://api.rubyonrails.org/classes/ActiveModel/Errors.html ActiveModel::Errors
49
+ # @raise [Error::ContextFailure]
50
+ def fail!(errors = nil)
51
+ merge_errors!(errors) if errors
52
+ @_failed = true
53
+ raise Error::ContextFailure, self
54
+ end
55
+
56
+ # Whether the context instance has failed. By default, a new
57
+ # context is successful and only changes when explicitly failed
58
+ # @note The {#failure?} method is the inverse of the {#success?} method
59
+ # @example Check if a context has failed
60
+ # class MyInteractor < ActiveInteractor::Base
61
+ # def perform; end
62
+ # end
63
+ #
64
+ # result = MyInteractor.perform
65
+ # #=> <#MyInteractor::Context>
66
+ #
67
+ # result.failure?
68
+ # #=> false
69
+ # @return [Boolean] `false` by default or `true` if failed
70
+ def failure?
71
+ @_failed || false
72
+ end
73
+ alias fail? failure?
74
+
75
+ # Roll back an interactor context. Any interactors to which this
76
+ # context has been passed and which have been successfully called are asked
77
+ # to roll themselves back by invoking their
78
+ # {ActiveInteractor::Base#rollback} instance methods.
79
+ # @example Rollback an interactor's context
80
+ # class MyInteractor < ActiveInteractor::Base
81
+ # def perform
82
+ # context.fail!
83
+ # end
84
+ #
85
+ # def rollback
86
+ # context.user&.destroy
87
+ # end
88
+ # end
89
+ #
90
+ # user = User.create
91
+ # #=> <#User>
92
+ #
93
+ # result = MyInteractor.perform(user: user)
94
+ # #=> <#MyInteractor::Context user=<#User>>
95
+ #
96
+ # result.user.destroyed?
97
+ # #=> true
98
+ # @return [Boolean] `true` if rolled back successfully or `false` if already
99
+ # rolled back
100
+ def rollback!
101
+ return false if @_rolled_back
102
+
103
+ _called.reverse_each(&:rollback)
104
+ @_rolled_back = true
105
+ end
106
+
107
+ # Whether the context instance is successful. By default, a new
108
+ # context is successful and only changes when explicitly failed
109
+ # @note the {#success?} method is the inverse of the {#failure?} method
110
+ # @example Check if a context is successful
111
+ # class MyInteractor < ActiveInteractor::Base
112
+ # def perform; end
113
+ # end
114
+ #
115
+ # result = MyInteractor.perform
116
+ # #=> <#MyInteractor::Context>
117
+ #
118
+ # result.success?
119
+ # #=> true
120
+ # @return [Boolean] `true` by default or `false` if failed
121
+ def success?
122
+ !failure?
123
+ end
124
+ alias successful? success?
125
+
126
+ private
127
+
128
+ def _called
129
+ @_called ||= []
130
+ end
131
+
132
+ def merge_errors!(errors)
133
+ if errors.is_a? String
134
+ self.errors.add(:context, errors)
135
+ else
136
+ self.errors.merge!(errors)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ module ActiveInteractor
6
+ module Context
7
+ # @api private
8
+ # Load, find or create {Context::Base} classes for a given interactor.
9
+ # @author Aaron Allen <hello@aaronmallen.me>
10
+ # @since 1.0.0
11
+ module Loader
12
+ # @return [Array<Class>] ActiveInteractor base classes
13
+ BASE_CLASSES = [ActiveInteractor::Base, ActiveInteractor::Organizer].freeze
14
+ # @return [Class] the base context class
15
+ BASE_CONTEXT = ActiveInteractor::Context::Base
16
+
17
+ # Create a new context class on an interactor
18
+ # @param context_class_name [String] the name of the class to create
19
+ # @param interactor_class [Class] the interactor class to create the context for
20
+ # @return [Class] the created context class
21
+ def self.create(context_class_name, interactor_class)
22
+ interactor_class.const_set(context_class_name.to_s.classify, Class.new(BASE_CONTEXT))
23
+ end
24
+
25
+ # Find or create a new context class for an interactor
26
+ # @note the loader will attempt to find an existing context given the naming conventions:
27
+ # `MyInteractor::Context` or `MyInteractorContext`
28
+ # @param interactor_class [Class] the interactor class to find or create the context for
29
+ def self.find_or_create(interactor_class)
30
+ return BASE_CONTEXT if BASE_CLASSES.include?(interactor_class)
31
+
32
+ klass = possible_classes(interactor_class).first
33
+ klass || create('Context', interactor_class)
34
+ end
35
+
36
+ def self.possible_classes(interactor_class)
37
+ ["#{interactor_class.name}::Context", "#{interactor_class.name}Context"]
38
+ .map(&:safe_constantize)
39
+ .compact
40
+ .reject { |klass| klass&.name&.include?('ActiveInteractor') }
41
+ end
42
+ private_class_method :possible_classes
43
+ end
44
+ end
45
+ end
@@ -1,30 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveInteractor
4
- # ActiveInteractor::Error module
5
- #
4
+ # ActiveInteractor errors
6
5
  # @author Aaron Allen <hello@aaronmallen.me>
7
6
  # @since 0.1.5
8
- # @version 0.1
9
7
  module Error
10
- # Raised when an interactor context fails
11
- #
12
- # @author Aaron Allen <hello@aaronmallen.me>
13
- # @since 0.1.5
14
- # @version 0.1
15
- #
8
+ # Raised when an interactor context fails.
16
9
  # @!attribute [r] context
17
- # @return [Base] an instance of {Base}
10
+ # @return [Context::Base] an instance of {Context::Base}
18
11
  class ContextFailure < StandardError
19
12
  attr_reader :context
20
13
 
21
- # A new instance of {ContextFailure}
22
- # @param context [ActiveInteractor::Context::Base] an
23
- # instance of {ActiveInteractor::Context::Base}
24
- # @return [ContextFailure] a new instance of {ContextFailure}
14
+ # @param context [Context::Base] the failed context instance.
15
+ # @return [ContextFailure] a new instance of {ContextFailure}.
25
16
  def initialize(context = nil)
26
17
  @context = context
27
- super
18
+ context_class_name = context&.class&.name || 'Context'
19
+ super("#{context_class_name} failed!")
20
+ end
21
+ end
22
+
23
+ # Raised when an invalid context class is assigned to an interactor.
24
+ # @since 1.0.0
25
+ # @!attribute [r] class_name
26
+ # @return [String|nil] the class name of the context
27
+ class InvalidContextClass < StandardError
28
+ attr_reader :class_name
29
+
30
+ # @param class_name [String] the context class name
31
+ # @return [InvalidContextClass] a new instance of {InvalidContextClass}
32
+ def initialize(class_name = nil)
33
+ @class_name = class_name
34
+ super("invalid context class #{class_name}")
28
35
  end
29
36
  end
30
37
  end
@@ -1,65 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveInteractor
4
- # Provides interactor methods to included classes
5
- #
4
+ # Interactor methods. {Base} includes {Interactor} all interactors
5
+ # should inherit from {Base}.
6
6
  # @author Aaron Allen <hello@aaronmallen.me>
7
7
  # @since 0.0.1
8
- # @version 0.1
9
8
  module Interactor
10
- extend ActiveSupport::Concern
11
-
12
- included do
13
- extend ClassMethods
14
- include Callbacks
15
- include Context
16
- include Execution
17
-
18
- private
19
-
20
- attr_accessor :context
9
+ def self.included(base)
10
+ base.class_eval do
11
+ extend ClassMethods
12
+ include Callbacks
13
+ include Context
14
+ delegate :execute_perform, :execute_perform!, :execute_rollback, to: :worker
15
+ end
21
16
  end
22
-
17
+ # Interactor class methods.
23
18
  module ClassMethods
24
- # Invoke an interactor. This is the primary public API method to an
25
- # interactor.
26
- #
19
+ # Run an interactor context. This it the primary API method for
20
+ # interacting with interactors.
27
21
  # @example Run an interactor
28
22
  # MyInteractor.perform(name: 'Aaron')
29
23
  # #=> <#MyInteractor::Context name='Aaron'>
30
- #
31
- # @param context [Hash] properties to assign to the interactor context
32
- # @return [ActiveInteractor::Context::Base] an instance of context
24
+ # @param context [Hash|Context::Base] properties to assign to
25
+ # an interactor's context.
26
+ # @return [Context::Base] an instance of context.
33
27
  def perform(context = {})
34
28
  new(context).execute_perform
35
29
  end
36
30
 
37
- # Invoke an Interactor. The {.perform!} method behaves identically to
31
+ # Run an interactor context. The {.perform!} method behaves identically to
38
32
  # the {.perform} method with one notable exception. If the context is failed
39
- # during invocation of the interactor, the {ActiveInteractor::Error::ContextFailure}
33
+ # during invocation of the interactor, the {Error::ContextFailure}
40
34
  # is raised.
41
- #
42
35
  # @example Run an interactor
43
36
  # MyInteractor.perform!(name: 'Aaron')
44
37
  # #=> <#MyInteractor::Context name='Aaron'>
45
- #
46
- # @param context [Hash] properties to assign to the interactor context
47
- # @return [ActiveInteractor::Context::Base] an instance of context
38
+ # @param context [Hash|Context::Base] properties to assign to the interactor context.
39
+ # @raise [Error::ContextFailure] if the context fails.
40
+ # @return [Context::Base] an instance of context.
48
41
  def perform!(context = {})
49
42
  new(context).execute_perform!
50
43
  end
51
44
  end
52
45
 
53
- # Whether or not the context should fail when invalid
54
- # this will return false if
55
- # {Interactor::Callbacks::ClassMethods#allow_context_to_be_invalid}
56
- # has been invoked on the class.
57
- # @return [Boolean] `true` if the context should fail
58
- # `false` if it should not.
59
- def fail_on_invalid_context?
60
- self.class.__fail_on_invalid_context
61
- end
62
-
63
46
  # Invoke an Interactor instance without any hooks, tracking, or rollback
64
47
  # @abstract It is expected that the {#perform} method is overwritten
65
48
  # for each interactor class.
@@ -70,28 +53,12 @@ module ActiveInteractor
70
53
  # failure is expected to overwrite the {#rollback} method.
71
54
  def rollback; end
72
55
 
73
- # Whether or not the context should be cleaned after {#perform}
74
- # if {#skip_clean_context!} has not been invoked on the instance
75
- # and {Interactor::Callbacks::ClassMethods#clean_context_on_completion}
76
- # is invoked on the class this will return `true`.
77
- #
78
- # @return [Boolean] `true` if the context should be cleaned
79
- # `false` if it should not be cleaned.
80
- def should_clean_context?
81
- @should_clean_context.nil? && self.class.__clean_after_perform
82
- end
56
+ private
83
57
 
84
- # Skip {ActiveInteractor::Context::Attributes#clean! #clean! on an interactor
85
- # context that calls the {Callbacks.clean_context_on_completion} class method.
86
- # This method is meant to be invoked by organizer interactors
87
- # to ensure contexts are approriately passed between interactors.
88
- #
89
- # @return [Boolean] `true` if the context should be cleaned
90
- # `false` if it should not.
91
- def skip_clean_context!
92
- @should_clean_context = false
58
+ def worker
59
+ Worker.new(self)
93
60
  end
94
61
  end
95
62
  end
96
63
 
97
- Dir[File.expand_path('interactor/*.rb', __dir__)].each { |file| require file }
64
+ Dir[File.expand_path('interactor/*.rb', __dir__)].sort.each { |file| require file }
@@ -1,62 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/callbacks'
3
4
  require 'active_support/core_ext/array/extract_options'
4
5
  require 'active_support/core_ext/class/attribute'
5
6
 
6
7
  module ActiveInteractor
7
8
  module Interactor
8
- # Provides context attribute assignment methods to included classes
9
- #
9
+ # Interactor callback methods included by all {Base}
10
10
  # @author Aaron Allen <hello@aaronmallen.me>
11
11
  # @since 0.0.1
12
- # @version 0.1
13
12
  module Callbacks
14
- extend ActiveSupport::Concern
13
+ def self.included(base)
14
+ base.class_eval do
15
+ extend ClassMethods
16
+ include ActiveSupport::Callbacks
15
17
 
16
- included do
17
- extend ClassMethods
18
- include ActiveSupport::Callbacks
19
-
20
- class_attribute :__clean_after_perform, instance_writer: false, default: false
21
- class_attribute :__fail_on_invalid_context, instance_writer: false, default: true
22
- define_callbacks :validation,
23
- skip_after_callbacks_if_terminated: true,
24
- scope: %i[kind name]
25
- define_callbacks :perform, :rollback
18
+ define_callbacks :validation,
19
+ skip_after_callbacks_if_terminated: true,
20
+ scope: %i[kind name]
21
+ define_callbacks :perform, :rollback
22
+ end
26
23
  end
27
24
 
25
+ # Interactor callback class methods extended by all {Base}
28
26
  module ClassMethods
29
- # Define a callback to call after `#valid?` has been invoked on an
27
+ # Define a callback to call after {ActiveInteractor::Context::Base#valid? #valid?} has been invoked on an
30
28
  # interactor's context
31
- #
32
29
  # @example Implement an after_context_validation callback
33
30
  # class MyInteractor < ActiveInteractor::Base
34
- # after_context_validation :ensure_name_is_aaron
35
- # context_validates :name, inclusion: { in: %w[Aaron] }
31
+ # after_context_validation :downcase_name
32
+ #
33
+ # private
36
34
  #
37
- # def ensure_name_is_aaron
38
- # context.name = 'Aaron'
35
+ # def downcase_name
36
+ # context.name.downcase!
39
37
  # end
40
38
  # end
41
39
  #
42
- # context = MyInteractor.perform(name: 'Bob')
43
- # #=> <MyInteractor::Context name='Bob'>
40
+ # result = MyInteractor.perform(name: 'Aaron')
41
+ # #=> <MyInteractor::Context name='aaron'>
44
42
  #
45
- # context.valid?
46
- # #=> false
47
- #
48
- # context.name
49
- # #=> 'Aaron'
50
- #
51
- # context.valid?
43
+ # result.valid?
52
44
  # #=> true
45
+ #
46
+ # result.name
47
+ # #=> 'aaron'
53
48
  def after_context_validation(*args, &block)
54
49
  options = normalize_options(args.extract_options!.dup.merge(prepend: true))
55
50
  set_callback(:validation, :after, *args, options, &block)
56
51
  end
57
52
 
58
- # Define a callback to call after {ActiveInteractor::Base.perform} has been invoked
59
- #
53
+ # Define a callback to call after {Interactor#perform #perform} has been invoked
60
54
  # @example
61
55
  # class MyInteractor < ActiveInteractor::Base
62
56
  # after_perform :print_done
@@ -65,6 +59,8 @@ module ActiveInteractor
65
59
  # puts 'Performing'
66
60
  # end
67
61
  #
62
+ # private
63
+ #
68
64
  # def print_done
69
65
  # puts 'Done'
70
66
  # end
@@ -78,16 +74,21 @@ module ActiveInteractor
78
74
  set_callback(:perform, :after, *filters, &block)
79
75
  end
80
76
 
81
- # Define a callback to call after {ActiveInteractor::Base#rollback} has been invoked
82
- #
77
+ # Define a callback to call after {Interactor#rollback #rollback} has been invoked
83
78
  # @example
84
79
  # class MyInteractor < ActiveInteractor::Base
85
80
  # after_rollback :print_done
86
81
  #
82
+ # def perform
83
+ # context.fail!
84
+ # end
85
+ #
87
86
  # def rollback
88
87
  # puts 'Rolling back'
89
88
  # end
90
89
  #
90
+ # private
91
+ #
91
92
  # def print_done
92
93
  # puts 'Done'
93
94
  # end
@@ -103,17 +104,7 @@ module ActiveInteractor
103
104
  set_callback(:rollback, :after, *filters, &block)
104
105
  end
105
106
 
106
- # By default an interactor context will fail if it is deemed
107
- # invalid before or after the {ActiveInteractor::Base.perform} method
108
- # is invoked. Calling this method on an interactor class
109
- # will not invoke {ActiveInteractor::Context::Base#fail!} if the
110
- # context is invalid.
111
- def allow_context_to_be_invalid
112
- self.__fail_on_invalid_context = false
113
- end
114
-
115
- # Define a callback to call around {ActiveInteractor::Base.perform} invokation
116
- #
107
+ # Define a callback to call around {Interactor#perform #perform} invokation
117
108
  # @example
118
109
  # class MyInteractor < ActiveInteractor::Base
119
110
  # around_perform :track_time
@@ -122,6 +113,8 @@ module ActiveInteractor
122
113
  # sleep(1)
123
114
  # end
124
115
  #
116
+ # private
117
+ #
125
118
  # def track_time
126
119
  # context.start_time = Time.now.utc
127
120
  # yield
@@ -129,20 +122,19 @@ module ActiveInteractor
129
122
  # end
130
123
  # end
131
124
  #
132
- # context = MyInteractor.perform(name: 'Aaron')
125
+ # result = MyInteractor.perform(name: 'Aaron')
133
126
  # #=> <MyInteractor::Context name='Aaron'>
134
127
  #
135
- # context.start_time
128
+ # result.start_time
136
129
  # #=> 2019-01-01 00:00:00 UTC
137
130
  #
138
- # context.end_time
131
+ # result.end_time
139
132
  # #=> 2019-01-01 00:00:01 UTC
140
133
  def around_perform(*filters, &block)
141
134
  set_callback(:perform, :around, *filters, &block)
142
135
  end
143
136
 
144
- # Define a callback to call around {ActiveInteractor::Base#rollback} invokation
145
- #
137
+ # Define a callback to call around {Interactor#rollback #rollback} invokation
146
138
  # @example
147
139
  # class MyInteractor < ActiveInteractor::Base
148
140
  # around_rollback :track_time
@@ -151,6 +143,8 @@ module ActiveInteractor
151
143
  # sleep(1)
152
144
  # end
153
145
  #
146
+ # private
147
+ #
154
148
  # def track_time
155
149
  # context.start_time = Time.now.utc
156
150
  # yield
@@ -158,49 +152,48 @@ module ActiveInteractor
158
152
  # end
159
153
  # end
160
154
  #
161
- # context = MyInteractor.perform(name: 'Aaron')
155
+ # result = MyInteractor.perform(name: 'Aaron')
162
156
  # #=> <MyInteractor::Context name='Aaron'>
163
157
  #
164
- # context.rollback!
158
+ # result.rollback!
165
159
  # #=> true
166
160
  #
167
- # context.start_time
161
+ # result.start_time
168
162
  # #=> 2019-01-01 00:00:00 UTC
169
163
  #
170
- # context.end_time
164
+ # result.end_time
171
165
  # #=> 2019-01-01 00:00:01 UTC
172
166
  def around_rollback(*filters, &block)
173
167
  set_callback(:rollback, :around, *filters, &block)
174
168
  end
175
169
 
176
- # Define a callback to call before `#valid?` has been invoked on an
170
+ # Define a callback to call before {ActiveInteractor::Context::Base#valid? #valid?} has been invoked on an
177
171
  # interactor's context
178
- #
179
172
  # @example Implement an after_context_validation callback
180
173
  # class MyInteractor < ActiveInteractor::Base
181
- # before_context_validation :set_name_aaron
182
- # context_validates :name, inclusion: { in: %w[Aaron] }
174
+ # before_context_validation :downcase_name
183
175
  #
184
- # def set_name_aaron
185
- # context.name = 'Aaron'
176
+ # private
177
+ #
178
+ # def downcase_name
179
+ # context.name.downcase!
186
180
  # end
187
181
  # end
188
182
  #
189
- # context = MyInteractor.perform(name: 'Bob')
190
- # #=> <MyInteractor::Context name='Bob'>
183
+ # result = MyInteractor.perform(name: 'Aaron')
184
+ # #=> <MyInteractor::Context name='aaron'>
191
185
  #
192
- # context.valid?
186
+ # result.valid?
193
187
  # #=> true
194
188
  #
195
- # context.name
196
- # #=> 'Aaron'
189
+ # result.name
190
+ # #=> 'aaron'
197
191
  def before_context_validation(*args, &block)
198
192
  options = normalize_options(args.extract_options!.dup)
199
193
  set_callback(:validation, :before, *args, options, &block)
200
194
  end
201
195
 
202
- # Define a callback to call before {ActiveInteractor::Base.perform} has been invoked
203
- #
196
+ # Define a callback to call before {Interactor#perform #perform} has been invoked
204
197
  # @example
205
198
  # class MyInteractor < ActiveInteractor::Base
206
199
  # before_perform :print_start
@@ -209,6 +202,8 @@ module ActiveInteractor
209
202
  # puts 'Performing'
210
203
  # end
211
204
  #
205
+ # private
206
+ #
212
207
  # def print_start
213
208
  # puts 'Start'
214
209
  # end
@@ -222,8 +217,7 @@ module ActiveInteractor
222
217
  set_callback(:perform, :before, *filters, &block)
223
218
  end
224
219
 
225
- # Define a callback to call before {ActiveInteractor::Base#rollback} has been invoked
226
- #
220
+ # Define a callback to call before {Interactor#rollback #rollback} has been invoked
227
221
  # @example
228
222
  # class MyInteractor < ActiveInteractor::Base
229
223
  # before_rollback :print_start
@@ -232,6 +226,8 @@ module ActiveInteractor
232
226
  # puts 'Rolling Back'
233
227
  # end
234
228
  #
229
+ # private
230
+ #
235
231
  # def print_start
236
232
  # puts 'Start'
237
233
  # end
@@ -248,14 +244,6 @@ module ActiveInteractor
248
244
  set_callback(:rollback, :before, *filters, &block)
249
245
  end
250
246
 
251
- # Calling this method on an interactor class will invoke
252
- # {ActiveInteractor::Context::Base#clean!} on the interactor's
253
- # context instance after {ActiveInteractor::Base.perform}
254
- # is invoked.
255
- def clean_context_on_completion
256
- self.__clean_after_perform = true
257
- end
258
-
259
247
  private
260
248
 
261
249
  def normalize_options(options)