Class: Fresco::Action

Inherits:
Object
  • Object
show all
Defined in:
lib/fresco/runtime/runtime.rb

Direct Known Subclasses

Welcome

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAction

Per-instance filter state. @halt_response is left unset until halt! installs a real Response — #handle only reads it inside ‘if @halted` branches, so the uninitialised state is never observed.



352
353
354
# File 'lib/fresco/runtime/runtime.rb', line 352

def initialize
  @halted = false
end

Instance Attribute Details

#reqObject (readonly)

Returns the value of attribute req.



346
347
348
# File 'lib/fresco/runtime/runtime.rb', line 346

def req
  @req
end

Instance Method Details

#after_action(req, res) ⇒ Object



395
396
# File 'lib/fresco/runtime/runtime.rb', line 395

def after_action(req, res)
end

#before_action(req) ⇒ Object

Filter hooks. Default no-op bodies; subclasses opt in by overriding.



392
393
# File 'lib/fresco/runtime/runtime.rb', line 392

def before_action(req)
end

#call(req) ⇒ Object

Default #call — the polymorphic-dispatch anchor for Spinel’s bare ‘call(req)` inside #handle. Without this base definition the analyzer can’t resolve the call and emits 0 (mrb_int), which cascades into handle returning mrb_int and breaks every dispatcher call site.

Subclasses ALWAYS override. The body’s 500 also doubles as a safety net for actions that genuinely forgot to implement #call.

Spinel quirk worth knowing: this method dispatches polymorphically to subclass #call methods ONLY when their ‘req` param has a matching type. Subclass methods whose body doesn’t reference ‘req` need an explicit typed default — `def call(req = Request.new(“”, “”, “”))` — or Spinel collapses the param to mrb_int, the signature mismatches this base’s ‘sp_Request *`, and the case-on-cls_id dispatch falls back to this base (which always returns 500).



414
415
416
# File 'lib/fresco/runtime/runtime.rb', line 414

def call(req)
  Response.text(500, "Action is missing a #call implementation.\n")
end

#halt!(response) ⇒ Object

Short-circuit the filter chain. Sets the response that #handle will return in place of the normal #call result.



420
421
422
423
# File 'lib/fresco/runtime/runtime.rb', line 420

def halt!(response)
  @halted        = true
  @halt_response = response
end

#handle(req) ⇒ Object

Dispatcher entry point. Stashes ‘@req` on the instance so #render can reach the current request’s flash, then runs the before/after filter sandwich around the user-defined #call.

Filter contract:

1. #before_action runs first. It can halt!(resp) to skip #call.
2. #call runs only if no halt was requested.
3. #after_action runs after #call. It can also halt! to replace
   the response.

“Around” filters: override #handle in a subclass and call super. (See app/actions/filters/show.rb for the Spinel-shape workaround the super-assignment requires.)

Rails-style multi-callback chains (‘before_action :auth, :rate_limit`) aren’t viable under Spinel — they need ‘send(name)` for dynamic dispatch, which the analyzer rejects. Call helper methods explicitly from inside #before_action instead.



381
382
383
384
385
386
387
388
389
# File 'lib/fresco/runtime/runtime.rb', line 381

def handle(req)
  @req = req
  before_action(req)
  return @halt_response if @halted
  res = call(req)
  after_action(req, res)
  return @halt_response if @halted
  res
end

#layoutObject

Declare a layout by overriding ‘#layout` to return the symbol name of a layout under app/views/layouts/. Subclasses inherit via normal method lookup.



359
360
361
# File 'lib/fresco/runtime/runtime.rb', line 359

def layout
  :none
end

#redirect_to(location = "", status: 302) ⇒ Object



429
430
431
# File 'lib/fresco/runtime/runtime.rb', line 429

def redirect_to(location = "", status: 302)
  Response.redirect(location, status: status)
end

#render(body, status: 200) ⇒ Object



425
426
427
# File 'lib/fresco/runtime/runtime.rb', line 425

def render(body, status: 200)
  Response.html(status, dispatch_layout(layout, body, @req.flash))
end