Class: Ballast::Operation

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Interactor
Defined in:
lib/ballast/operation.rb

Overview

A operation represents a single responsibility class. Subclasses should only expose and override the #perform method.

Direct Known Subclasses

OperationsChain

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Operation) initialize(context)

Creates a new operation.

Parameters:

  • context (Context)

    The context for the operation.



29
30
31
32
# File 'lib/ballast/operation.rb', line 29

def initialize(context)
  @context = context
  setup
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method, *args, &block)

Forwards any missing method to the owner.

Parameters:

  • method (Symbol)

    The method to forward.

  • args (Array)

    The arguments to pass to the method.

  • block (Proc)

    The block to pass to the method.



128
129
130
131
132
133
134
# File 'lib/ballast/operation.rb', line 128

def method_missing(method, *args, &block)
  if owner.respond_to?(method)
    owner.send(method, *args, &block)
  else
    super(method, *args, &block)
  end
end

Class Method Details

+ (Operation) perform(owner_or_context, context: nil, params: {})

Performs the operation.

Parameters:

  • owner_or_context (Object|Context)

    If is a context, then it will be the context of the operation, otherwise a blank a context with the object as owner will be created.

  • context (NilClass)

    The context for the operation. Ignored if owner_or_context is a context.

  • params (Hash)

    The additional parameters for the new context. Ignored if owner_or_context is a context.

Returns:



20
21
22
23
24
# File 'lib/ballast/operation.rb', line 20

def self.perform(owner_or_context, context: nil, params: {})
  arg = owner_or_context
  arg = (context || ::Ballast::Context.build(owner_or_context, params)) if !arg.is_a?(::Ballast::Context)
  super(arg)
end

Instance Method Details

- (Object) fail!(error = nil)

Marks failure of the operation appending the error to the context.

Parameters:

  • error (Object|NilClass) (defaults to: nil)

    The error to store.



82
83
84
85
# File 'lib/ballast/operation.rb', line 82

def fail!(error = nil)
  errors << error if error
  super()
end

- (Object) import_error(target, to_flash = true, first_only = true)

Imports the current operation errors into the target’s @error instance variable or in the flash hash.

Parameters:

  • target (Object)

    The target of the import.

  • to_flash (Boolean) (defaults to: true)

    If to import the error in the target’s flash object rather than the instance variable.

  • first_only (Boolean) (defaults to: true)

    If to only import the first error.



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ballast/operation.rb', line 92

def import_error(target, to_flash = true, first_only = true)
  values = errors
  values = values.map {|v| v[:error] } if to_flash
  values = values.first if first_only

  if to_flash then
    target.flash[:error] = values
  else
    target.instance_variable_set(:@error, values)
  end
end

- (Object) import_response(target, overwrite: true, *fields)

Imports the response hash into the target instance variables.

Parameters:

  • target (Object)

    The target of the import.

  • fields (Array)

    The keys to import.

  • overwrite (Boolean)

    Whether to overwrite existing variables into the target. If set to false, any overwrite will raise an ArgumentError.



57
58
59
60
61
62
# File 'lib/ballast/operation.rb', line 57

def import_response(target, *fields, overwrite: true)
  fields.each do |field|
    raise ArgumentError.new(field) if target.instance_variable_get("@#{field}") && !overwrite
    target.instance_variable_set("@#{field}", response[field])
  end
end

- (Object) in_em_thread(&block)

If running under eventmachine, run the block in a thread of its threadpool using EM::Synchrony, otherwise run the block normally.

Parameters:

  • block (Proc)

    The block to run.



119
120
121
# File 'lib/ballast/operation.rb', line 119

def in_em_thread(&block)
  Ballast.in_em_thread(&block)
end

- (Object) perform_with_handling(setup_response_after = true)

Performs the operation handling base errors.

Parameters:

  • setup_response_after (Boolean) (defaults to: true)

    Whether to setup the response after processing.



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/ballast/operation.rb', line 67

def perform_with_handling(setup_response_after = true)
  begin
    yield
  rescue Lazier::Exceptions::Debug => de
    raise de
  rescue => e
    e.is_a?(::Ballast::Errors::BaseError) ? fail!(e.response) : raise(e)
  end

  setup_response if setup_response_after
end

- (String|Hash) resolve_error(error, supported_messages = {}, only_message = false)

Resolves a numeric error to a human readable message.

Parameters:

  • error (BaseError|Fixnum)

    The error to resolve.

  • supported_messages (Hash) (defaults to: {})

    The list of supported error codes.

  • only_message (Boolean) (defaults to: false)

    If to only return the message string rather than a full error hash.

Returns:

  • (String|Hash)

    The error with a human readable message or the message alone.



110
111
112
113
114
# File 'lib/ballast/operation.rb', line 110

def resolve_error(error, supported_messages = {}, only_message = false)
  code = (error.respond_to?(:response) ? error.response : 500).to_integer(500)
  rv = {status: code, error: supported_messages.fetch(code, "Oops! We're having some issue. Please try again later.")}
  only_message ? rv[:error] : rv
end

- (Hash) setup_response(force = false)

Sets up the response hash from instance variables.

Parameters:

  • force (Boolean) (defaults to: false)

    Whether to setup the response even if the operation failed.

Returns:

  • (Hash)

    The response hash.



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ballast/operation.rb', line 38

def setup_response(force = false)
  if success? || force then
    vars = instance_variables
    vars.delete(:@context)

    context.response.merge!(vars.reduce({}){ |rv, var|
      rv[var.to_s.gsub(/[:@]/, "")] = instance_variable_get(var)
      rv
    })
  end

  context.response
end