Class: Rails::UseCase

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Validations, Callable
Defined in:
lib/rails/use_case.rb,
lib/rails/use_case/outcome.rb

Overview

UseCase. See README.

Defined Under Namespace

Classes: Error, Outcome

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.stepsObject (readonly)

Returns the value of attribute steps.



17
18
19
# File 'lib/rails/use_case.rb', line 17

def steps
  @steps
end

Instance Attribute Details

#recordObject (readonly)

Returns the value of attribute record.



12
13
14
# File 'lib/rails/use_case.rb', line 12

def record
  @record
end

Class Method Details

.failure(code = nil, options = {}) ⇒ Object



57
58
59
60
# File 'lib/rails/use_case.rb', line 57

def self.failure(code = nil, options = {})
  options[:code] = code || options[:code] || :failure
  step :failure, options
end

.step(name = :inline, options = {}, &block) ⇒ Object

DSL to define a process step of the UseCase. You can use if/unless with a lambda in the options to conditionally skip the step.

Parameters:

  • name (Symbol) (defaults to: :inline)
  • options (Hash) (defaults to: {})


40
41
42
43
44
45
46
47
48
49
# File 'lib/rails/use_case.rb', line 40

def self.step(name = :inline, options = {}, &block)
  @steps ||= []

  if block_given?
    options[:do] = block
    name = :inline
  end

  @steps << { name: name.to_sym, options: options }
end

.success(options = {}) ⇒ Object



52
53
54
# File 'lib/rails/use_case.rb', line 52

def self.success(options = {})
  step :success, options
end

.with(mod) ⇒ Object

DSL to include a behavior.

Parameters:

  • mod (Module)


65
66
67
# File 'lib/rails/use_case.rb', line 65

def self.with(mod)
  include mod
end

Instance Method Details

#break_when_invalid!Object



129
130
131
132
133
# File 'lib/rails/use_case.rb', line 129

def break_when_invalid!
  return true if valid?

  fail! code: :validation_failed, message: errors.full_messages.join(', ')
end

#call(params) ⇒ Object

Will be called by Callable.call.

Parameters:

  • params (Hash)

    The arguments for the UseCase as Hash so we can auto assign instance variables.



24
25
26
27
28
29
30
31
# File 'lib/rails/use_case.rb', line 24

def call(params)
  prepare params
  process

  successful_outcome
rescue UseCase::Error => e
  failure_outcome e
end

#fail!(code: nil, message: 'Failed') ⇒ Object

Raises:



93
94
95
96
# File 'lib/rails/use_case.rb', line 93

def fail!(code: nil, message: 'Failed')
  @error_code = code
  raise UseCase::Error, message
end

#prepare(params) ⇒ Object

Prepare step. Runs automatically before the UseCase process starts. Sets all params as instance variables and then runs the validations.

Parameters:

  • params (Hash)


119
120
121
122
123
124
125
# File 'lib/rails/use_case.rb', line 119

def prepare(params)
  params.each do |key, value|
    instance_variable_set "@#{key}", value
  end

  break_when_invalid!
end

#processObject

Will run the steps of the use case.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rails/use_case.rb', line 71

def process
  self.class.steps.each do |step|
    # Check wether to skip when :if or :unless are set.
    next if skip_step?(step)

    opts = step[:options]
    name = step[:name]

    # Handle failure and success steps.
    return true if name == :success

    fail!(code: opts[:code], message: opts[:message]) if name == :failure

    # Run the lambda, when :do is set. Otherwise call the method.
    next if opts[:do] ? instance_eval(&opts[:do]) : send(name)

    # result is false, so we have a failure.
    fail! code: :step_false, message: "Step '#{name}' returned false"
  end
end

#skip_step?(step) ⇒ Boolean

Checks whether to skip a step.

Parameters:

  • step (Hash)

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rails/use_case.rb', line 101

def skip_step?(step)
  if step[:options][:if]
    proc = step[:options][:if]
    result = instance_exec(&proc)
    return true unless result
  end

  return false unless step[:options][:unless]

  proc = step[:options][:unless]
  result = instance_exec(&proc)
  return true if result
end