Class: BugBunny::Controller
- Inherits:
-
Object
- Object
- BugBunny::Controller
- Includes:
- ActiveModel::Attributes, ActiveModel::Model, Observability
- Defined in:
- lib/bug_bunny/controller.rb
Overview
Clase base para todos los Controladores de Mensajes en BugBunny.
Actúa como el receptor final de los mensajes enrutados desde el consumidor. Implementa un ciclo de vida similar a ActionController en Rails, soportando:
-
Filtros (‘before_action`, `around_action`, `after_action`).
-
Manejo declarativo de errores (‘rescue_from`).
-
Parsing de parámetros unificados (‘params`).
-
Respuestas estructuradas (‘render`).
Constant Summary
Constants included from Observability
Atributos de Instancia collapse
-
#rendered_response ⇒ Hash?
readonly
Respuesta final renderizada.
-
#response_headers ⇒ Hash
Headers que se enviarán en la respuesta.
Atributos de Instancia collapse
-
#headers ⇒ Hash
Metadatos del mensaje entrante (ej. HTTP method, routing_key, id).
-
#params ⇒ ActiveSupport::HashWithIndifferentAccess
Parámetros unificados (Body JSON + Query String).
-
#raw_string ⇒ String
Cuerpo crudo original en caso de no ser JSON.
Class Method Summary collapse
-
.after_action(method_name, **options) ⇒ void
Registra un filtro que se ejecutará **después** de la acción.
-
.around_action(method_name, **options) ⇒ void
Registra un filtro que envuelve la ejecución de la acción.
-
.before_action(method_name, **options) ⇒ void
Registra un filtro que se ejecutará antes de la acción.
-
.call(headers:, body: {}) ⇒ Hash
Punto de entrada principal estático llamado por el Router (‘BugBunny::Consumer`).
-
.register_callback(collection_name, method_name, options) ⇒ Object
private
Helper interno para registrar callbacks garantizando Thread-Safety e Inmutabilidad del padre.
-
.rescue_from(*klasses, with: nil) {|Exception| ... } ⇒ Object
Manejo declarativo de excepciones.
Instance Method Summary collapse
-
#initialize(attributes = {}) ⇒ Controller
constructor
A new instance of Controller.
-
#process(body) ⇒ Hash
Ejecuta el ciclo de vida completo de la petición: Params -> Before -> Action -> Rescue.
Methods included from Observability
Constructor Details
#initialize(attributes = {}) ⇒ Controller
Returns a new instance of Controller.
142 143 144 145 146 |
# File 'lib/bug_bunny/controller.rb', line 142 def initialize(attributes = {}) super @response_headers = {}.with_indifferent_access @logger = BugBunny.configuration.logger end |
Instance Attribute Details
#rendered_response ⇒ Hash? (readonly)
Returns Respuesta final renderizada.
39 40 41 |
# File 'lib/bug_bunny/controller.rb', line 39 def rendered_response @rendered_response end |
#response_headers ⇒ Hash
Returns Headers que se enviarán en la respuesta.
36 37 38 |
# File 'lib/bug_bunny/controller.rb', line 36 def response_headers @response_headers end |
Class Method Details
.after_action(method_name, **options) ⇒ void
This method returns an undefined value.
Registra un filtro que se ejecutará **después** de la acción. No se ejecuta si un ‘before_action` halted la cadena (render anticipado) ni si la acción lanzó una excepción, siguiendo el comportamiento de Rails.
82 83 84 |
# File 'lib/bug_bunny/controller.rb', line 82 def self.after_action(method_name, **) register_callback(:after_actions, method_name, ) end |
.around_action(method_name, **options) ⇒ void
This method returns an undefined value.
Registra un filtro que envuelve la ejecución de la acción. El método registrado debe invocar ‘yield` para continuar la ejecución.
71 72 73 |
# File 'lib/bug_bunny/controller.rb', line 71 def self.around_action(method_name, **) register_callback(:around_actions, method_name, ) end |
.before_action(method_name, **options) ⇒ void
This method returns an undefined value.
Registra un filtro que se ejecutará antes de la acción. Si el filtro invoca ‘render`, la cadena se interrumpe y la acción no se ejecuta.
61 62 63 |
# File 'lib/bug_bunny/controller.rb', line 61 def self.before_action(method_name, **) register_callback(:before_actions, method_name, ) end |
.call(headers:, body: {}) ⇒ Hash
Punto de entrada principal estático llamado por el Router (‘BugBunny::Consumer`).
153 154 155 |
# File 'lib/bug_bunny/controller.rb', line 153 def self.call(headers:, body: {}) new(headers: headers).process(body) end |
.register_callback(collection_name, method_name, options) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Helper interno para registrar callbacks garantizando Thread-Safety e Inmutabilidad del padre.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/bug_bunny/controller.rb', line 115 def self.register_callback(collection_name, method_name, ) current_hash = send(collection_name) # Deep dup: Clonamos el hash y sus arrays internos para no modificar la clase padre new_hash = current_hash.transform_values(&:dup) only = Array([:only]).map(&:to_sym) target_actions = only.empty? ? [:_all_actions] : only target_actions.each do |action| new_hash[action] ||= [] new_hash[action] << method_name end send("#{collection_name}=", new_hash) end |
.rescue_from(*klasses, with: nil) {|Exception| ... } ⇒ Object
Manejo declarativo de excepciones. Atrapa errores específicos que ocurran durante la ejecución de la acción.
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/bug_bunny/controller.rb', line 99 def self.rescue_from(*klasses, with: nil, &block) handler = with || block raise ArgumentError, "Need a handler. Supply 'with: :method' or a block." unless handler # Duplicamos el array del padre para no mutarlo al registrar reglas en el hijo new_handlers = rescue_handlers.dup klasses.each do |klass| new_handlers.unshift([klass, handler]) end self.rescue_handlers = new_handlers end |
Instance Method Details
#headers ⇒ Hash
Returns Metadatos del mensaje entrante (ej. HTTP method, routing_key, id).
27 |
# File 'lib/bug_bunny/controller.rb', line 27 attribute :headers |
#params ⇒ ActiveSupport::HashWithIndifferentAccess
Returns Parámetros unificados (Body JSON + Query String).
30 |
# File 'lib/bug_bunny/controller.rb', line 30 attribute :params |
#process(body) ⇒ Hash
Ejecuta el ciclo de vida completo de la petición: Params -> Before -> Action -> Rescue.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/bug_bunny/controller.rb', line 161 def process(body) prepare_params(body) action_name = headers[:action].to_sym current_arounds = resolve_callbacks(self.class.around_actions, action_name) # Definir el núcleo de ejecución core_execution = proc do return unless run_before_actions(action_name) raise NameError, "Action '#{action_name}' not found in #{self.class.name}" unless respond_to?(action_name) public_send(action_name) run_after_actions(action_name) end # Construir e invocar la cadena de responsabilidad (Middlewares/Around Actions) execution_chain = current_arounds.reverse.inject(core_execution) do |next_step, method_name| -> { send(method_name, &next_step) } end execution_chain.call # Si no hubo renderización explícita, devuelve 204 No Content rendered_response || { status: 204, headers: response_headers, body: nil } rescue StandardError => e handle_exception(e) end |
#raw_string ⇒ String
Returns Cuerpo crudo original en caso de no ser JSON.
33 |
# File 'lib/bug_bunny/controller.rb', line 33 attribute :raw_string |