Class: FService::Result::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/f_service/result/base.rb

Overview

This class is abstract.

Abstract base class for Result::Success and Result::Failure.

Direct Known Subclasses

Failure, Success

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(types = []) ⇒ Base

You usually shouldn’t call this directly. See Base#Failure and Base#Success.



19
20
21
22
23
# File 'lib/f_service/result/base.rb', line 19

def initialize(types = [])
  @handled = false
  @types = types
  @matching_types = []
end

Instance Attribute Details

#typesObject (readonly)



10
11
12
# File 'lib/f_service/result/base.rb', line 10

def types
  @types
end

Instance Method Details

#on_failure(*target_types, unhandled: false) {|value, type| ... } ⇒ Success, Failure

This hook runs if the result is failed. Can receive one or more types to be checked before running the given block.

Examples:

class UsersController < BaseController
  def update
    User::Update.(user: user)
                .on_success { |value| return json_success(value) } # this won't run
                .on_failure(:type, :type2) { |error| return json_error(error) } # runs only if type matches
                .on_failure { |error| return json_error(error) }
  end

  private

  def user
    @user ||= User.find_by!(slug: params[:slug])
  end
end
class UsersController < BaseController
  def update
    User::Update.(user: user)
                .on_success(:unhandled: true) { |value| return json_success(value) } # this won't run
                .on_failure(:type, :type2) { |error| return json_error(error) } # runs only if type matches
                .on_failure(:unhandled: true) { |error| return json_error(error) }
  end

  private

  def user
    @user ||= User.find_by!(slug: params[:slug])
  end
end

Yield Parameters:

  • value

    value of the failure object

  • type

    type of the failure object

Returns:



121
122
123
124
125
126
127
128
129
130
# File 'lib/f_service/result/base.rb', line 121

def on_failure(*target_types, unhandled: false)
  if failed? && unhandled? && expected_type?(target_types, unhandled: unhandled)
    match_types(target_types)
    yield(*to_ary)
    @handled = true
    freeze
  end

  self
end

#on_success(*target_types, unhandled: false) {|value, type| ... } ⇒ Success, Failure

This hook runs if the result is successful. Can receive one or more types to be checked before running the given block.

Examples:

class UsersController < BaseController
  def update
    User::Update.(user: user)
                .on_success(:type, :type2) { return json_success({ status: :ok }) } # run only if type matches
                .on_success { |value| return json_success(value) }
                .on_failure { |error| return json_error(error) } # this won't run
  end

  private

  def user
    @user ||= User.find_by!(slug: params[:slug])
  end
end
class UsersController < BaseController
  def update
    User::Update.(user: user)
                .on_success(:type, :type2) { return json_success({ status: :ok }) } # run only if type matches
                .on_success(unhandled: true) { |value| return json_success(value) }
                .on_failure(unhandled: true) { |error| return json_error(error) } # this won't run
  end

  private

  def user
    @user ||= User.find_by!(slug: params[:slug])
  end
end

Yield Parameters:

  • value

    value of the failure object

  • type

    type of the failure object

Returns:



71
72
73
74
75
76
77
78
79
80
# File 'lib/f_service/result/base.rb', line 71

def on_success(*target_types, unhandled: false)
  if successful? && unhandled? && expected_type?(target_types, unhandled: unhandled)
    match_types(target_types)
    yield(*to_ary)
    @handled = true
    freeze
  end

  self
end

#to_aryArray

Splits the result object into its components.

Returns:

  • (Array)

    value and type of the result object



135
136
137
138
139
# File 'lib/f_service/result/base.rb', line 135

def to_ary
  data = successful? ? value : error

  [data, @matching_types.first]
end

#typeObject

Implements old attribute type. Its deprecated in favor of using types.



26
27
28
29
30
# File 'lib/f_service/result/base.rb', line 26

def type
  FService.deprecate!(name: "#{self.class}##{__method__}", alternative: '#types', from: caller[0])

  types.size == 1 ? types.first : Array(@matching_types).first
end