The following diagram describes some of Rage's internal components and the way they interact with each other:
When Rage::Router::DSL
parses the config/routes.rb
file and calls the Rage::Router::Backend
class, it registers actions and stores handler procs.
Consider we have the following controller:
class UsersController < RageController::API
before_action :find_user
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
def show
render json: @user
end
private
def find_user
@user = User.find(params[:id])
end
def render_not_found(_)
render status: :not_found
end
end
Before processing requests to UsersController#show
, Rage has to register the show action. Registering means defining a new method that will look like this:
class UsersController
def __run_show
find_user
show
rescue ActiveRecord::RecordNotFound => e
render_not_found(e)
end
end
After that, Rage will create and store a handler proc that will look exactly like this:
->(env, params) { UsersController.new(env, params).__run_show }
All of this happens at boot time. Once the request comes in at runtime, Rage will only need to retrieve the handler proc defined earlier and call it.