Class: Telephone::Service

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model
Defined in:
lib/telephone/service.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) {|_self| ... } ⇒ Service

Primary responsibility of initialize is to instantiate the attributes of the service object with the expected values.

Yields:

  • (_self)

Yield Parameters:



22
23
24
25
26
27
28
29
# File 'lib/telephone/service.rb', line 22

def initialize(attributes = {})
  self.class.defaults.merge(attributes).each do |key, value|
    send("#{key}=", value)
  end

  super
  yield self if block_given?
end

Instance Attribute Details

#resultObject

The primary outcome of the service object. For consistency, all service objects always return self. If you need a value returned, the return value of #call will be available on the attribute @result.

Examples:

Telephone::Service.call(foo: bar).result # "baz"


17
18
19
# File 'lib/telephone/service.rb', line 17

def result
  @result
end

Class Method Details

.argument(arg, default: nil, required: false) ⇒ Object

Defines a getter/setter for a service object argument. This also allows you to pass in a default, or set the argument to “required” to add a validation that runs before executing the block.

Examples:

class SomeService < Telephone::Service
  argument :foo, default: "bar"
  argument :baz, required: true

  def call
    puts foo
    puts baz
  end
end


64
65
66
67
68
69
# File 'lib/telephone/service.rb', line 64

def argument(arg, default: nil, required: false)
  send(:attr_accessor, arg.to_sym)
  send(:validates, arg.to_sym, presence: true) if required

  defaults[arg.to_sym] = default
end

.call(**args) ⇒ Object

Executes the service object action directly from the class — similar to the way a Proc can be executed with ‘Proc#call`. This allows us to add some common logic around running validations and setting argument defaults.

Examples:

Telephone::Service.call(foo: bar)


85
86
87
# File 'lib/telephone/service.rb', line 85

def call(**args)
  new(args).call
end

.defaultsObject

Used to maintain a list of default values to set prior to initialization based on the options in #argument.



74
75
76
# File 'lib/telephone/service.rb', line 74

def defaults
  @defaults ||= {}
end

.method_added(method_name) ⇒ Object

When the subclass overwrites the #call method, reassign it to #__call. This allows us to still control what happens in the instance level of #call.



92
93
94
95
96
97
98
99
# File 'lib/telephone/service.rb', line 92

def method_added(method_name)
  if method_name == :call
    alias_method :__call, :call
    send(:remove_method, :call)
  else
    super
  end
end

Instance Method Details

#callObject



43
44
45
46
# File 'lib/telephone/service.rb', line 43

def call
  self.result = __call if valid?
  self
end

#success?Boolean

Determines whether or not the action of the service object was successful.

Examples:

Telephone::Service.call(foo: bar).success? # true

Returns:

  • (Boolean)

    whether or not the action succeeded.



39
40
41
# File 'lib/telephone/service.rb', line 39

def success?
  errors.empty?
end