@@ -585,7 +585,7 @@ After loading the framework and any gems in your application, Rails turns to loa
NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the initializers folder on down.
TIP: If you have any ordering dependency in your initializers, you can control the load order by naming. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
TIP: If you have any ordering dependency in your initializers, you can control the load order through naming. Initializer files are loaded in alphabetical order by their path. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
This guide explains the internals of the initialization process in Rails as of Rails 3.1. It is an extremely in-depth guide and recommended for advanced Rails developers.
This guide explains the internals of the initialization process in Rails
as of Rails 4. It is an extremely in-depth guide and recommended for advanced Rails developers.
* Using +rails server+
* Using Passenger
endprologue.
This guide goes through every single file, class and method call that is required to boot up the Ruby on Rails stack for a default Rails 3.1 application, explaining each part in detail along the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application.
This guide goes through every single file, class and method call that is
required to boot up the Ruby on Rails stack for a default Rails 4 application, explaining each part in detail along the way. For this guide, we will be focusing on how the two most common methods (+rails server+ and Passenger) boot a Rails application.
NOTE: Paths in this guide are relative to Rails or a Rails application unless otherwise specified.
...
...
@@ -22,16 +24,15 @@ The actual +rails+ command is kept in _bin/rails_:
The +rbconfig+ file from the Ruby standard library provides us with the +RbConfig+ class which contains detailed information about the Ruby environment, including how Ruby was compiled. We can see thisin use in +railties/lib/rails/script_rails_loader+.
The +rbconfig+ file from the Ruby standard library provides us with the +RbConfig+ class which contains detailed information about the Ruby environment, including how Ruby was compiled. We can see thisin use in +railties/lib/rails/script_rails_loader+.
<ruby>
require 'pathname'
...
...
@@ -120,6 +121,9 @@ exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
This is effectively the same as running +ruby script/rails [arguments]+, where +[arguments]+ at this point in time is simply "server".
TIP: If you execute +script/rails+ directly from your Rails app you will
avoid executing the code that we just described.
h4. +script/rails+
This file is as follows:
...
...
@@ -134,23 +138,23 @@ The +APP_PATH+ constant will be used later in +rails/commands+. The +config/boot
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
</ruby>
In a standard Rails application, there's a +Gemfile+ which declares all dependencies of the application. +config/boot.rb+ sets +ENV["BUNDLE_GEMFILE"]+ to the location of this file, then requires Bundler and calls +Bundler.setup+ which adds the dependencies of the application (including all the Rails parts) to the load path, making them available for the application to load. The gems that a Rails 3.1 application depends on are as follows:
In a standard Rails application, there's a +Gemfile+ which declares all
dependencies of the application. +config/boot.rb+ sets
+ENV['BUNDLE_GEMFILE']+ to the location of this file. If the Gemfile
exists, +bundler/setup+ is then required.
The gems that a Rails 4 application depends on are as follows:
TODO: change these when the Rails 4 release is near.
* abstract (1.0.0)
* actionmailer (3.1.0.beta)
...
...
@@ -183,6 +187,8 @@ h4. +rails/commands.rb+
Once +config/boot.rb+ has finished, the next file that is required is +rails/commands+ which will execute a command based on the arguments passed in. In this case, the +ARGV+ array simply contains +server+ which is extracted into the +command+ variable using these lines:
<ruby>
ARGV << '--help' if ARGV.empty?
aliases = {
"g" => "generate",
"c" => "console",
...
...
@@ -195,6 +201,9 @@ command = ARGV.shift
command = aliases[command] || command
</ruby>
TIP: As you can see, an empty ARGV list will make Rails show the help
snippet.
If we used <tt>s</tt> rather than +server+, Rails will use the +aliases+ defined in the file and match them to their respective commands. With the +server+ command, Rails will run this code:
<ruby>
...
...
@@ -361,8 +370,9 @@ This method is defined like this:
# The '-h' option calls exit before @options is set.
...
...
@@ -380,10 +399,18 @@ ensure
end
</ruby>
This is where the first output of the Rails initialization happens. This method creates a trap for +INT+ signals, so if you +CTRL+C+ the server, it will exit the process. As we can see from the code here, it will create the +tmp/cache+, +tmp/pids+, +tmp/sessions+ and +tmp/sockets+ directories if they don't already exist prior to calling +super+. The +super+ method will call +Rack::Server.start+ which begins its definition like this:
This is where the first output of the Rails initialization happens. This
method creates a trap for +INT+ signals, so if you +CTRL-C+ the server,
it will exit the process. As we can see from the code here, it will
create the +tmp/cache+, +tmp/pids+, +tmp/sessions+ and +tmp/sockets+
directories. It then calls +wrapped_app+ which is responsible for
creating the Rack app, before creating and assignig an
instance of +ActiveSupport::Logger+.
The +super+ method will call +Rack::Server.start+ which begins its definition like this:
<ruby>
def start
def start &blk
if options[:warn]
$-w = true
end
...
...
@@ -403,22 +430,37 @@ def start
pp wrapped_app
pp app
end
end
</ruby>
In a Rails application, these options are not set at all and therefore aren't used at all. The first line of code that's executed in this method is a call to this method:
check_pid! if options[:pid]
<ruby>
wrapped_app
# Touch the wrapped app, so that the config.ru is loaded before
# daemonization (i.e. before chdir, etc).
wrapped_app
daemonize_app if options[:daemonize]
write_pid if options[:pid]
trap(:INT) do
if server.respond_to?(:shutdown)
server.shutdown
else
exit
end
end
server.run wrapped_app, options, &blk
end
</ruby>
This method calls another method:
The interesting part for a Rails app is the last line, +server.run+. Here we encounter the +wrapped_app+ method again, which this time
we're going to explore more.
<ruby>
@wrapped_app ||= build_app app
</ruby>
Then the +app+ method here is defined like so:
The +app+ method here is defined like so:
<ruby>
def app
...
...
@@ -440,7 +482,7 @@ The +options[:config]+ value defaults to +config.ru+ which contains this:
# This file is used by Rack-based servers to start the application.