From 830226cca10c05765933ab1c9720d0bbea6e6467 Mon Sep 17 00:00:00 2001 From: Roman Samoilov <2270393+rsamoilov@users.noreply.github.com> Date: Fri, 3 May 2024 12:30:48 +0100 Subject: [PATCH] Add `Cascade` this allows to have both Rails and Rage controllers in one application --- lib/rage-rb.rb | 4 ++++ lib/rage/router/backend.rb | 14 ++++++++++---- lib/rage/router/util.rb | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/rage-rb.rb b/lib/rage-rb.rb index 5a76bd8e..76131079 100644 --- a/lib/rage-rb.rb +++ b/lib/rage-rb.rb @@ -24,6 +24,10 @@ def self.application end end + def self.multi_application + Rage::Router::Util::Cascade.new(application, Rails.application) + end + def self.routes Rage::Router::DSL.new(__router) end diff --git a/lib/rage/router/backend.rb b/lib/rage/router/backend.rb index 6979e92a..7dcd6d45 100644 --- a/lib/rage/router/backend.rb +++ b/lib/rage/router/backend.rb @@ -68,12 +68,18 @@ def on(method, path, handler, constraints: {}, defaults: nil) raise "Invalid route handler format, expected to match the 'controller#action' pattern" unless handler =~ STRING_HANDLER_REGEXP controller, action = Rage::Router::Util.path_to_class($1), $2 - run_action_method_name = controller.__register_action(action.to_sym) - meta[:controller] = $1 - meta[:action] = $2 + if controller.ancestors.include?(RageController::API) + run_action_method_name = controller.__register_action(action.to_sym) - handler = eval("->(env, params) { #{controller}.new(env, params).#{run_action_method_name} }") + meta[:controller] = $1 + meta[:action] = $2 + + handler = eval("->(env, params) { #{controller}.new(env, params).#{run_action_method_name} }") + else + # this is a Rails controller; notify `Rage::Router::Util::Cascade` to forward the request to Rails + handler = ->(_, _) { [404, { "X-Cascade" => "pass" }, []] } + end else raise "Non-string route handler should respond to `call`" unless handler.respond_to?(:call) # while regular handlers are expected to be called with the `env` and `params` objects, diff --git a/lib/rage/router/util.rb b/lib/rage/router/util.rb index 929d630e..9c9527b6 100644 --- a/lib/rage/router/util.rb +++ b/lib/rage/router/util.rb @@ -30,4 +30,19 @@ def path_to_name(str) end end end + + # @private + class Cascade + def initialize(rage_app, rails_app) + @rage_app = rage_app + @rails_app = rails_app + end + + def call(env) + result = @rage_app.call(env) + return result if result[0] == :__http_defer__ || result[1]["X-Cascade".freeze] != "pass".freeze + + @rails_app.call(env) + end + end end