Module: Interaktor

Defined in:
lib/interaktor.rb

Defined Under Namespace

Modules: Callable, ClassMethods, Hooks, Organizer Classes: Context, Failure

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

When the Interaktor module is included in a class, add the relevant class methods and hooks to that class.

Parameters:

  • base (Class)

    the class which is including the Interaktor module



12
13
14
15
16
17
18
# File 'lib/interaktor.rb', line 12

def self.included(base)
  base.class_eval do
    extend ClassMethods
    include Hooks
    include Callable
  end
end

Instance Method Details

#callvoid

This method returns an undefined value.

Invoke an Interaktor instance without any hooks, tracking, or rollback. It is expected that the #call instance method is overwritten for each interaktor class.



70
# File 'lib/interaktor.rb', line 70

def call; end

#fail!(failure_attributes = {}) ⇒ void

This method returns an undefined value.

Fail the current interaktor.

Parameters:

  • failure_attributes (Hash{Symbol=>Object}) (defaults to: {})

    the context attributes

Raises:



34
35
36
37
38
39
40
41
42
# File 'lib/interaktor.rb', line 34

def fail!(failure_attributes = {})
  # Make sure we have all required attributes
  missing_attrs = self.class
                      .failure_attributes
                      .reject { |failure_attr| failure_attributes.key?(failure_attr) }
  raise Interaktor::Error::MissingAttributeError.new(self.class.to_s, missing_attrs) if missing_attrs.any?

  @context.fail!(failure_attributes)
end

#initialize(context = {}) ⇒ Object

Parameters:

  • context (Hash, Interaktor::Context) (defaults to: {})

    the context object as a hash with attributes or an already-built context



25
26
27
# File 'lib/interaktor.rb', line 25

def initialize(context = {})
  @context = Interaktor::Context.build(context)
end

#rollbackvoid

This method returns an undefined value.

Reverse prior invocation of an Interaktor instance. Any interaktor class that requires undoing upon downstream failure is expected to overwrite the #rollback instance method.



77
# File 'lib/interaktor.rb', line 77

def rollback; end

#runvoid

This method returns an undefined value.

Invoke an interaktor instance along with all defined hooks. The run method is used internally by the call class method. After successful invocation of the interaktor, the instance is tracked within the context. If the context is failed or any error is raised, the context is rolled back.



86
87
88
89
# File 'lib/interaktor.rb', line 86

def run
  run!
rescue Interaktor::Failure # rubocop:disable Lint/SuppressedException
end

#run!void

This method returns an undefined value.

Invoke an Interaktor instance along with all defined hooks, typically used internally by .call!. After successful invocation of the interaktor, the instance is tracked within the context. If the context is failed or any error is raised, the context is rolled back. This method behaves identically to #run with one notable exception - if the context is failed during the invocation of the interaktor, Interaktor::Failure is raised.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/interaktor.rb', line 101

def run!
  with_hooks do
    catch(:early_return) do
      call
    end

    if !@context.early_return? && self.class.success_attributes.any?
      raise Interaktor::Error::MissingAttributeError.new(self, self.class.success_attributes)
    end

    @context.called!(self)
  end
rescue StandardError
  @context.rollback!
  raise
end

#success!(success_attributes = {}) ⇒ void

This method returns an undefined value.

Terminate execution of the current interaktor and copy the success attributes into the context.

Parameters:

  • success_attributes (Hash{Symbol=>Object}) (defaults to: {})

    the context attributes

Raises:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/interaktor.rb', line 50

def success!(success_attributes = {})
  # Make sure we have all required attributes
  missing_attrs = self.class
                      .success_attributes
                      .reject { |success_attr| success_attributes.key?(success_attr) }
  raise Interaktor::Error::MissingAttributeError.new(self.class.to_s, missing_attrs) if missing_attrs.any?

  # Make sure we haven't provided any unknown attributes
  unknown_attrs = success_attributes.keys
                                    .reject { |success_attr| self.class.success_attributes.include?(success_attr) }
  raise Interaktor::Error::UnknownAttributeError.new(self.class.to_s, unknown_attrs) if unknown_attrs.any?

  @context.success!(success_attributes)
end