Class: Praxis::RequestStages::RequestStage

Inherits:
Stage
  • Object
show all
Defined in:
lib/praxis/request_stages/request_stage.rb

Overview

Special Stage what will hijack the run and execute methods to: 1- Run specific controller callbacks (in addition to any normal callbacks) 2- Shortcut the controller callback chain if any returns a Response object

Instance Attribute Summary

Attributes inherited from Stage

#after_callbacks, #before_callbacks, #context, #name, #stages

Instance Method Summary collapse

Methods inherited from Stage

#after, #application, #before, #callback_args, #execute_callbacks, #initialize, #setup_deferred_callbacks!

Constructor Details

This class inherits a constructor from Praxis::Stage

Instance Method Details

#actionObject



39
40
41
# File 'lib/praxis/request_stages/request_stage.rb', line 39

def action
  @context.action
end

#controllerObject



35
36
37
# File 'lib/praxis/request_stages/request_stage.rb', line 35

def controller
  @context.controller
end

#executeObject

Raises:

  • (NotImplementedError)


105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/praxis/request_stages/request_stage.rb', line 105

def execute
  raise NotImplementedError, 'Subclass must implement Stage#execute' unless @stages.any?

  @stages.each do |stage|
    shortcut = stage.run
    if shortcut.is_a?(Praxis::Response)
      controller.response = shortcut
      return shortcut
    end
  end
  nil
end

#execute_controller_callbacks(callbacks) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/praxis/request_stages/request_stage.rb', line 15

def execute_controller_callbacks(callbacks)
  if callbacks.key?(path)
    callbacks[path].each do |(conditions, block)|
      next if conditions.key?(:actions) && !(conditions[:actions].include? action.name)

      result = block.call(controller)
      if result.is_a?(Praxis::Response)
        controller.response = result
        return result
      end
    end
  end

  nil
end

#execute_with_aroundObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/praxis/request_stages/request_stage.rb', line 79

def execute_with_around
  cb = controller.class.around_callbacks[path]
  if cb.nil? || cb.empty?
    execute
  else
    inner_proc = proc { execute }

    applicable = cb.select do |(conditions, _handler)|
      if conditions.key?(:actions)
        conditions[:actions].include?(action.name) ? true : false
      else
        true
      end
    end

    chain = applicable.reverse.inject(inner_proc) do |blk, (_conditions, handler)|
      if blk
        proc { handler.call(controller, blk) }
      else
        proc { handler.call }
      end
    end
    chain.call
  end
end

#pathObject



11
12
13
# File 'lib/praxis/request_stages/request_stage.rb', line 11

def path
  @path ||= [name].freeze
end

#requestObject



43
44
45
# File 'lib/praxis/request_stages/request_stage.rb', line 43

def request
  @context.request
end

#runObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/praxis/request_stages/request_stage.rb', line 51

def run
  # stage-level callbacks (typically empty) will never shortcut
  execute_callbacks(before_callbacks)

  r = execute_controller_callbacks(controller.class.before_callbacks)
  # Shortcut lifecycle if filters return non-nil value
  # (which should only be a Response)
  return r if r

  result = execute_with_around
  # Shortcut lifecycle if filters return a response
  # (non-nil but non-response-class response is ignored)
  if result.is_a?(Praxis::Response)
    controller.response = result
    return result
  end

  r = execute_controller_callbacks(controller.class.after_callbacks)
  # Shortcut lifecycle if filters return non-nil value
  # (which should only be a Response)
  return r if r

  # stage-level callbacks (typically empty) will never shortcut
  execute_callbacks(after_callbacks)

  result
end

#setup!Object



31
32
33
# File 'lib/praxis/request_stages/request_stage.rb', line 31

def setup!
  setup_deferred_callbacks!
end

#validation_handlerObject



47
48
49
# File 'lib/praxis/request_stages/request_stage.rb', line 47

def validation_handler
  dispatcher.application.validation_handler
end