Rack specifies
A Rack application is a Ruby object (not a class) that responds to call.
Consequently, a simple config.ru
looks like this:
class MyApp
def call(env)
[200, {"Content-Type" => "text/plain"}, ["Hello from Rack!\n"]]
end
end
run MyApp.new
while Rails generates this:
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run RailsApp::Application
So, I'm wondering: Why not run RailsApp::Application.new
when Rack specifies it to be an object, not a class? Is there something special about Rails::Application
that I'm missing?
config.ru is a Rack configuration file ( ru stands for "rackup"). Rack provides a minimal interface between web servers that support Ruby and Ruby frameworks. It's like a Ruby implementation of a CGI which offers a standard protocol for web servers to execute programs.
The configuration file config/application. rb and environment-specific configuration files (such as config/environments/production. rb ) allow you to specify the various settings that you want to pass down to all of the components. Rails will use that particular setting to configure Active Record.
Go to your browser and open http://localhost:3000, you will see a basic Rails app running. You can also use the alias "s" to start the server: bin/rails s . The server can be run on a different port using the -p option. The default development environment can be changed using -e .
This is indeed a bit hidden :)
RailsApp::Application
is a child class of Rails::Application
, which in turn is a Rails::Engine
which is a Rails::Railtie
. Now Rails::Railtie
has an inherited
hook which is called whenever a child class inherits from the Railtie class (in this case Engine
).
This callback includes the Rails::Railtie::Configurable
module into the subclass. In this module, you find the first part of the magic.
The method_missing
method which gets defined on the class calls the method on an instance of the class, which more or less resolves to
RailsApp::Application.new.call(...)
This call
instance method is defined in Rails::Application#call
and does the typical Rack handing.
There is probably still a bit more magic involved which makes it not 100% equivalent but that should roughly be it...
A Class is also an Object. Rack doesn't instantiate the app object (which is why it specifies you need to provide the object), you do that in config.ru
, so provided the Rails class object follows all the Rack rules when Rack sends 'call', it should not be a problem.
Internally, I don't know whether Rails does anything special on call
. It could even be a factory method that both spits out an instance of the application class and runs it. But it doesn't need to be to satisfy Rack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With