This post will take you through the sequence of code calls that use the Rails Server command to the application launch, describe the boot process for Rails server, a brief translation of rails guide and some bloggers, and please forgive me for the bad translation. Look at the time, it is best to find a copy of the source code of RAILS4 together against the view.
Original address: http://guides.ruby-china.org/initialization.html
When we use Rails C (onsole) or Rails s (erver) to start a rails application, rails s actually executes a ruby script under the current path:
Version = ">=0" Load Gem.bin_path (' railties ', ' rails ', version)
If you enter the above command in the Rails console, you will see that railties/bin/rails is executed.
In the last line of Railties/bin/rails source, you can see
Require "RAILS/CLI"
Require RAILTIES/LIB/RAILS/CLI, continue to follow up, in the RAILTIES/LIB/RAILS/CLI:
Require ' Rails/app_rails_loader ' # If We is inside a rails application This method performs an exec and thus# the rest of This script was not run. Rails::apprailsloader.exec_app_rails
Continue into railties/lib/rails/app_rails_loader.rb
ruby = gem.rubyexecutables = [' bin/rails ', ' script/rails ']......class << self ...... def exec_app_rails original_cwd = Dir.pwd loop do if exe = find_executable contents = file.read (EXE) if contents =~ /(APP| ENGINE) _path/ exec ruby, exe, *ARGV break # non reachable, hack to be able to stub exec in the test suite &Nbsp; elsif exe.end_with? (' Bin/rails ') && contents.include? (' This file was generated by bundler ') $stderr. Puts (bundler_warning) object.const_set (: App_path, file.expand_path (' config/application ', Dir.pwd)) require file.expand_path ('.. /boot ', app_path) require ' Rails/commands ' break end end # if we exhaust the search there is no executable, this could be a # call to generate a new application, so restore the original cwd. dir.chdir (ORIGINAL_CWD) and return if pathname.new (dir.pwd) .root? # otherwise keep moving upwards in search of an executable. dir.chdir ('.. ') end end def find_executable executables.find { |exe| file.file? (EXE) } endend
You can see from the above code that rails::apprailsloader.exec_app_rails will find Bin/rails or script/rails in the current directory, and it will execute:
exec Gem.ruby, bin/rails, *ARGV
That is equivalent to
EXEC Ruby Bin/rails Server
If there is no bin/rails or script/rails in the current directory, it will continue recursively up until the bin (script)/rails is found, so rails server or rails can be used anywhere in the rails project's root directory and subdirectories Console command
Bin/rails:
#!/usr/bin/env Rubyapp_path = File.expand_path ('.. /.. /config/application ', __file__) require_relative '. /config/boot ' Require ' rails/commands '
App_path constants will be used later in the Rails/commands ,require_relative '. /config/boot ' is require the config/boot.rb file, BOOT.RB is responsible for loading the boot bundler
Config/boot.rb
# Set up gems listed in the gemfile.env[' Bundle_gemfile ' | | = File.expand_path ('.. /.. /gemfile ', __file__) require ' bundler/setup ' if file.exist? (env[' Bundle_gemfile ')
In a standard rails application, the Gemfile file declares all application dependencies, env[' Bundle_gemfile '] stores gemfile file addresses, when gemfile files exist, goes back to require Bundle/setup, The path used for bundler configuration to load gemfile dependencies.
A standard rails application needs to rely on several gem packages, such as:
Actionmailer
Actionpack
Actionview
Activemodel
ActiveRecord
Activesupport
Arel
Builder
Bundler
Erubis
i18n
Mail
Mime-types
Polyglot
Rack
Rack-cache
Rack-mount
Rack-test
Rails
Railties
Rake
Sqlite3
Thor
Treetop
Tzinfo
Require config/boot.rb back to bin/rails, and finally require rails/commands
Rails/commands.rb
Used primarily to extend the aliases of Rails command parameters:
Rails/commands.rb
ARGV << '--help ' if argv.empty? aliases = {"G" = "Generate", "D" = "Destroy", "c" = "console", "s" = "" Server "," db "=" = "Dbcon Sole "," r "=" Runner "} command = Argv.shiftcommand = Aliases[command] | | Command require ' rails/commands/commands_tasks ' rails::commandstasks.new (ARGV). run_command! (command)
You can see that when you do not pass arguments, it is actually equivalent to rails--help, and rails S is equivalent to the Rails server
Rails/commands/command_tasks.rb
When an incorrect rails command is entered, the Run_command method is responsible for throwing an error message. If the command is valid, the method with the same name is called
command_whitelist = % (plugin generate destroy console server dbconsole &NBSP;APPLICATION&NBSP;RUNNER&NBSP;NEW&NBSP;VERSION&NBSP;HELP) def run_command! (command) command = parse_command (command) if command_whitelist.include? (command) send (command) else write_error_message ( command) endenddef write_error_message (command) puts "Error: command ' #{command} ' not recognized ' if %x{rake #{command} --dry-run 2 >&1 } && $?. success? puts "did you mean: ' $ rake #{command} ' ?\n \ n " end write_help_message exit (1) end def parse_command (command) case command when ' --version ', '-V ' ' version ' when '--help ', '-h ' ' Help ' else command endend
Wait, go on.
RAILS4 startup process