Class: BugBunny::Controller

Inherits:
Object
  • Object
show all
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`).

Author:

  • Gabriel

Since:

  • 3.0.6

Constant Summary

Constants included from Observability

Observability::SENSITIVE_KEYS

Atributos de Instancia collapse

Atributos de Instancia collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Observability

sensitive_key?

Constructor Details

#initialize(attributes = {}) ⇒ Controller

Returns a new instance of Controller.

Since:

  • 3.0.6



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_responseHash? (readonly)

Returns Respuesta final renderizada.

Returns:

  • (Hash, nil)

    Respuesta final renderizada.

Since:

  • 3.0.6



39
40
41
# File 'lib/bug_bunny/controller.rb', line 39

def rendered_response
  @rendered_response
end

#response_headersHash

Returns Headers que se enviarán en la respuesta.

Returns:

  • (Hash)

    Headers que se enviarán en la respuesta.

Since:

  • 3.0.6



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.

Parameters:

  • method_name (Symbol)

    Nombre del método privado a ejecutar.

  • options (Hash)

    Opciones como ‘only: [:create, :update]`.

Since:

  • 3.0.6



82
83
84
# File 'lib/bug_bunny/controller.rb', line 82

def self.after_action(method_name, **options)
  register_callback(:after_actions, method_name, options)
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.

Parameters:

  • method_name (Symbol)

    Nombre del método privado a ejecutar.

  • options (Hash)

    Opciones como ‘only: [:index]`.

Since:

  • 3.0.6



71
72
73
# File 'lib/bug_bunny/controller.rb', line 71

def self.around_action(method_name, **options)
  register_callback(:around_actions, method_name, options)
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.

Parameters:

  • method_name (Symbol)

    Nombre del método privado a ejecutar.

  • options (Hash)

    Opciones como ‘only: [:show, :update]`.

Since:

  • 3.0.6



61
62
63
# File 'lib/bug_bunny/controller.rb', line 61

def self.before_action(method_name, **options)
  register_callback(:before_actions, method_name, options)
end

.call(headers:, body: {}) ⇒ Hash

Punto de entrada principal estático llamado por el Router (‘BugBunny::Consumer`).

Parameters:

  • headers (Hash)

    Metadatos y variables de enrutamiento.

  • body (String, Hash) (defaults to: {})

    El payload del mensaje AMQP.

Returns:

  • (Hash)

    Respuesta final estructurada.

Since:

  • 3.0.6



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.

Since:

  • 3.0.6



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, options)
  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(options[: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.

Examples:

rescue_from Api::Error::NotFound, with: :render_not_found
rescue_from StandardError do |e|
  render status: 500, json: { error: e.message }
end

Parameters:

  • klasses (Array<Class, String>)

    Clases de excepciones a atrapar.

  • with (Symbol, nil) (defaults to: nil)

    Nombre del método manejador.

Yields:

  • (Exception)

    Bloque opcional para manejar el error inline.

Raises:

  • (ArgumentError)

    Si no se provee un manejador (with o block).

Since:

  • 3.0.6



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

#headersHash

Returns Metadatos del mensaje entrante (ej. HTTP method, routing_key, id).

Returns:

  • (Hash)

    Metadatos del mensaje entrante (ej. HTTP method, routing_key, id).

Since:

  • 3.0.6



27
# File 'lib/bug_bunny/controller.rb', line 27

attribute :headers

#paramsActiveSupport::HashWithIndifferentAccess

Returns Parámetros unificados (Body JSON + Query String).

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)

    Parámetros unificados (Body JSON + Query String).

Since:

  • 3.0.6



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.

Parameters:

  • body (String, Hash)

    El cuerpo del mensaje.

Returns:

  • (Hash)

    La respuesta lista para ser enviada vía RabbitMQ RPC.

Since:

  • 3.0.6



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_stringString

Returns Cuerpo crudo original en caso de no ser JSON.

Returns:

  • (String)

    Cuerpo crudo original en caso de no ser JSON.

Since:

  • 3.0.6



33
# File 'lib/bug_bunny/controller.rb', line 33

attribute :raw_string