railties 3.1.1 → 3.1.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +2382 -0
- data/guides/output/2_2_release_notes.html +565 -0
- data/guides/output/2_3_release_notes.html +713 -0
- data/guides/output/3_0_release_notes.html +652 -0
- data/guides/output/3_1_release_notes.html +670 -0
- data/guides/output/action_controller_overview.html +925 -0
- data/guides/output/action_mailer_basics.html +658 -0
- data/guides/output/action_view_overview.html +1471 -0
- data/guides/output/active_model_basics.html +349 -0
- data/guides/output/active_record_basics.html +364 -0
- data/guides/output/active_record_querying.html +1272 -0
- data/guides/output/active_record_validations_callbacks.html +1292 -0
- data/guides/output/active_resource_basics.html +252 -0
- data/guides/output/active_support_core_extensions.html +3374 -0
- data/guides/output/ajax_on_rails.html +412 -0
- data/guides/output/api_documentation_guidelines.html +317 -0
- data/guides/output/asset_pipeline.html +691 -0
- data/guides/output/association_basics.html +1742 -0
- data/guides/output/caching_with_rails.html +533 -0
- data/guides/output/command_line.html +662 -0
- data/guides/output/configuring.html +811 -0
- data/guides/output/contribute.html +216 -0
- data/guides/output/contributing_to_ruby_on_rails.html +465 -0
- data/guides/output/credits.html +210 -0
- data/guides/output/debugging_rails_applications.html +791 -0
- data/guides/output/engines.html +673 -0
- data/guides/output/form_helpers.html +850 -0
- data/guides/output/generators.html +725 -0
- data/guides/output/getting_started.html +1980 -0
- data/guides/output/i18n.html +1054 -0
- data/guides/output/images/belongs_to.png +0 -0
- data/guides/output/images/book_icon.gif +0 -0
- data/guides/output/images/bullet.gif +0 -0
- data/guides/output/images/challenge.png +0 -0
- data/guides/output/images/chapters_icon.gif +0 -0
- data/guides/output/images/check_bullet.gif +0 -0
- data/guides/output/images/credits_pic_blank.gif +0 -0
- data/guides/output/images/csrf.png +0 -0
- data/guides/output/images/customized_error_messages.png +0 -0
- data/guides/output/images/edge_badge.png +0 -0
- data/guides/output/images/error_messages.png +0 -0
- data/guides/output/images/feature_tile.gif +0 -0
- data/guides/output/images/footer_tile.gif +0 -0
- data/guides/output/images/fxn.png +0 -0
- data/guides/output/images/grey_bullet.gif +0 -0
- data/guides/output/images/habtm.png +0 -0
- data/guides/output/images/has_many.png +0 -0
- data/guides/output/images/has_many_through.png +0 -0
- data/guides/output/images/has_one.png +0 -0
- data/guides/output/images/has_one_through.png +0 -0
- data/guides/output/images/header_backdrop.png +0 -0
- data/guides/output/images/header_tile.gif +0 -0
- data/guides/output/images/i18n/demo_html_safe.png +0 -0
- data/guides/output/images/i18n/demo_localized_pirate.png +0 -0
- data/guides/output/images/i18n/demo_translated_en.png +0 -0
- data/guides/output/images/i18n/demo_translated_pirate.png +0 -0
- data/guides/output/images/i18n/demo_translation_missing.png +0 -0
- data/guides/output/images/i18n/demo_untranslated.png +0 -0
- data/guides/output/images/icons/README +5 -0
- data/guides/output/images/icons/callouts/1.png +0 -0
- data/guides/output/images/icons/callouts/10.png +0 -0
- data/guides/output/images/icons/callouts/11.png +0 -0
- data/guides/output/images/icons/callouts/12.png +0 -0
- data/guides/output/images/icons/callouts/13.png +0 -0
- data/guides/output/images/icons/callouts/14.png +0 -0
- data/guides/output/images/icons/callouts/15.png +0 -0
- data/guides/output/images/icons/callouts/2.png +0 -0
- data/guides/output/images/icons/callouts/3.png +0 -0
- data/guides/output/images/icons/callouts/4.png +0 -0
- data/guides/output/images/icons/callouts/5.png +0 -0
- data/guides/output/images/icons/callouts/6.png +0 -0
- data/guides/output/images/icons/callouts/7.png +0 -0
- data/guides/output/images/icons/callouts/8.png +0 -0
- data/guides/output/images/icons/callouts/9.png +0 -0
- data/guides/output/images/icons/caution.png +0 -0
- data/guides/output/images/icons/example.png +0 -0
- data/guides/output/images/icons/home.png +0 -0
- data/guides/output/images/icons/important.png +0 -0
- data/guides/output/images/icons/next.png +0 -0
- data/guides/output/images/icons/note.png +0 -0
- data/guides/output/images/icons/prev.png +0 -0
- data/guides/output/images/icons/tip.png +0 -0
- data/guides/output/images/icons/up.png +0 -0
- data/guides/output/images/icons/warning.png +0 -0
- data/guides/output/images/jaimeiniesta.jpg +0 -0
- data/guides/output/images/nav_arrow.gif +0 -0
- data/guides/output/images/polymorphic.png +0 -0
- data/guides/output/images/posts_index.png +0 -0
- data/guides/output/images/radar.png +0 -0
- data/guides/output/images/rails_guides_logo.gif +0 -0
- data/guides/output/images/rails_logo_remix.gif +0 -0
- data/guides/output/images/rails_welcome.png +0 -0
- data/guides/output/images/session_fixation.png +0 -0
- data/guides/output/images/tab_grey.gif +0 -0
- data/guides/output/images/tab_info.gif +0 -0
- data/guides/output/images/tab_note.gif +0 -0
- data/guides/output/images/tab_red.gif +0 -0
- data/guides/output/images/tab_yellow.gif +0 -0
- data/guides/output/images/tab_yellow.png +0 -0
- data/guides/output/images/validation_error_messages.png +0 -0
- data/guides/output/images/vijaydev.jpg +0 -0
- data/guides/output/index.html +300 -0
- data/guides/output/initialization.html +1087 -0
- data/guides/output/javascripts/guides.js +7 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
- data/guides/output/javascripts/syntaxhighlighter/shCore.js +17 -0
- data/guides/output/layout.html +312 -0
- data/guides/output/layouts_and_rendering.html +1257 -0
- data/guides/output/migrations.html +751 -0
- data/guides/output/nested_model_forms.html +350 -0
- data/guides/output/performance_testing.html +858 -0
- data/guides/output/plugins.html +590 -0
- data/guides/output/rails_application_templates.html +368 -0
- data/guides/output/rails_on_rack.html +408 -0
- data/guides/output/routing.html +1246 -0
- data/guides/output/ruby_on_rails_guides_guidelines.html +218 -0
- data/guides/output/security.html +968 -0
- data/guides/output/stylesheets/fixes.css +16 -0
- data/guides/output/stylesheets/main.css +445 -0
- data/guides/output/stylesheets/print.css +52 -0
- data/guides/output/stylesheets/reset.css +43 -0
- data/guides/output/stylesheets/style.css +13 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCore.css +226 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
- data/guides/output/testing.html +1182 -0
- data/guides/source/active_record_validations_callbacks.textile +3 -3
- data/guides/source/active_support_core_extensions.textile +2 -2
- data/guides/source/asset_pipeline.textile +7 -5
- data/guides/source/association_basics.textile +2 -4
- data/guides/source/command_line.textile +1 -1
- data/guides/source/configuring.textile +4 -2
- data/guides/source/contributing_to_ruby_on_rails.textile +6 -6
- data/guides/source/initialization.textile +2 -2
- data/guides/source/performance_testing.textile +1 -1
- data/guides/source/routing.textile +1 -1
- data/guides/source/security.textile +2 -2
- data/lib/rails/commands/server.rb +1 -1
- data/lib/rails/engine.rb +1 -1
- data/lib/rails/generators/app_base.rb +2 -1
- data/lib/rails/generators/base.rb +3 -3
- data/lib/rails/generators/rails/app/templates/gitignore +15 -5
- data/lib/rails/rack.rb +0 -1
- data/lib/rails/tasks/documentation.rake +7 -7
- data/lib/rails/tasks/misc.rake +0 -2
- data/lib/rails/test_unit/testing.rake +2 -0
- data/lib/rails/version.rb +2 -2
- metadata +495 -326
- data/CHANGELOG +0 -2371
- data/lib/rails/rack/content_length.rb +0 -38
@@ -0,0 +1,1087 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
+
|
8
|
+
<title>Ruby on Rails Guides: The Rails Initialization Process</title>
|
9
|
+
|
10
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
|
11
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
|
12
|
+
|
13
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
|
14
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
|
15
|
+
|
16
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
|
17
|
+
</head>
|
18
|
+
<body class="guide">
|
19
|
+
<div id="topNav">
|
20
|
+
<div class="wrapper">
|
21
|
+
<strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
|
22
|
+
<a href="http://rubyonrails.org/">Overview</a> |
|
23
|
+
<a href="http://rubyonrails.org/download">Download</a> |
|
24
|
+
<a href="http://rubyonrails.org/deploy">Deploy</a> |
|
25
|
+
<a href="https://github.com/rails/rails">Code</a> |
|
26
|
+
<a href="http://rubyonrails.org/screencasts">Screencasts</a> |
|
27
|
+
<a href="http://rubyonrails.org/documentation">Documentation</a> |
|
28
|
+
<a href="http://rubyonrails.org/ecosystem">Ecosystem</a> |
|
29
|
+
<a href="http://rubyonrails.org/community">Community</a> |
|
30
|
+
<a href="http://weblog.rubyonrails.org/">Blog</a>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div id="header">
|
34
|
+
<div class="wrapper clearfix">
|
35
|
+
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
|
36
|
+
<p class="hide"><a href="#mainCol">Skip navigation</a>.</p>
|
37
|
+
<ul class="nav">
|
38
|
+
<li><a href="index.html">Home</a></li>
|
39
|
+
<li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">Guides Index</a>
|
40
|
+
<div id="guides" class="clearfix" style="display: none;">
|
41
|
+
<hr />
|
42
|
+
<dl class="L">
|
43
|
+
<dt>Start Here</dt>
|
44
|
+
<dd><a href="getting_started.html">Getting Started with Rails</a></dd>
|
45
|
+
<dt>Models</dt>
|
46
|
+
<dd><a href="migrations.html">Rails Database Migrations</a></dd>
|
47
|
+
<dd><a href="active_record_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
|
48
|
+
<dd><a href="association_basics.html">Active Record Associations</a></dd>
|
49
|
+
<dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
|
50
|
+
<dt>Views</dt>
|
51
|
+
<dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
|
52
|
+
<dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
|
53
|
+
<dt>Controllers</dt>
|
54
|
+
<dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
|
55
|
+
<dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
|
56
|
+
</dl>
|
57
|
+
<dl class="R">
|
58
|
+
<dt>Digging Deeper</dt>
|
59
|
+
<dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
|
60
|
+
<dd><a href="i18n.html">Rails Internationalization API</a></dd>
|
61
|
+
<dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
|
62
|
+
<dd><a href="testing.html">Testing Rails Applications</a></dd>
|
63
|
+
<dd><a href="security.html">Securing Rails Applications</a></dd>
|
64
|
+
<dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
|
65
|
+
<dd><a href="performance_testing.html">Performance Testing Rails Applications</a></dd>
|
66
|
+
<dd><a href="configuring.html">Configuring Rails Applications</a></dd>
|
67
|
+
<dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
|
68
|
+
<dd><a href="caching_with_rails.html">Caching with Rails</a></dd>
|
69
|
+
<dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
|
70
|
+
|
71
|
+
<dt>Extending Rails</dt>
|
72
|
+
<dd><a href="plugins.html">The Basics of Creating Rails Plugins</a></dd>
|
73
|
+
<dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
|
74
|
+
<dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
|
75
|
+
|
76
|
+
<dt>Contributing to Ruby on Rails</dt>
|
77
|
+
<dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
|
78
|
+
<dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
|
79
|
+
<dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
|
80
|
+
|
81
|
+
<dt>Release Notes</dt>
|
82
|
+
<dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
|
83
|
+
<dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
|
84
|
+
<dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
|
85
|
+
<dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
|
86
|
+
</dl>
|
87
|
+
</div>
|
88
|
+
</li>
|
89
|
+
<li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li>
|
90
|
+
<li><a href="credits.html">Credits</a></li>
|
91
|
+
</ul>
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
<hr class="hide" />
|
95
|
+
|
96
|
+
<div id="feature">
|
97
|
+
<div class="wrapper">
|
98
|
+
<h2>The Rails Initialization Process</h2>
|
99
|
+
<p>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.</p>
|
100
|
+
<ul>
|
101
|
+
<li>Using <tt>rails server</tt></li>
|
102
|
+
<li>Using Passenger</li>
|
103
|
+
</ul>
|
104
|
+
|
105
|
+
<div id="subCol">
|
106
|
+
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
|
107
|
+
<ol class="chapters">
|
108
|
+
<li><a href="#launch">Launch!</a><ul><li><a href="#bin-rails"><tt>bin/rails</tt></a></li> <li><a href="#railties-lib-rails-cli-rb"><tt>railties/lib/rails/cli.rb</tt></a></li> <li><a href="#script-rails"><tt>script/rails</tt></a></li> <li><a href="#config-boot-rb"><tt>config/boot.rb</tt></a></li> <li><a href="#rails-commands-rb"><tt>rails/commands.rb</tt></a></li> <li><a href="#actionpack-lib-action_dispatch-rb"><tt>actionpack/lib/action_dispatch.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-rb"><tt>activesupport/lib/active_support.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-lazy_load_hooks-rb"><tt>activesupport/lib/active_support/lazy_load_hooks.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-inflector-methods-rb"><tt>activesupport/lib/active_support/inflector/methods.rb</tt></a></li> <li><a href="#actionpack-lib-action_dispatch-rb-cont-d"><tt>actionpack/lib/action_dispatch.rb</tt> cont’d.</a></li> <li><a href="#rails-commands-server-rb"><tt>rails/commands/server.rb</tt></a></li> <li><a href="#rack-lib-rack-server-rb">Rack: <tt>lib/rack/server.rb</tt></a></li> <li><a href="#rails-server-start"><tt>Rails::Server#start</tt></a></li> <li><a href="#config-environment-rb"><tt>config/environment.rb</tt></a></li> <li><a href="#config-application-rb"><tt>config/application.rb</tt></a></li></ul></li><li><a href="#loading-rails">Loading Rails</a><ul><li><a href="#railties-lib-rails-all-rb"><tt>railties/lib/rails/all.rb</tt></a></li> <li><a href="#railties-lib-rails-rb"><tt>railties/lib/rails.rb</tt></a></li> <li><a href="#railties-lib-rails-ruby_version_check-rb"><tt>railties/lib/rails/ruby_version_check.rb</tt></a></li> <li><a href="#active_support-core_ext-kernel-reporting-rb"><tt>active_support/core_ext/kernel/reporting.rb</tt></a></li> <li><a href="#active_support-core_ext-logger-rb"><tt>active_support/core_ext/logger.rb</tt></a></li> <li><a href="#railties-lib-rails-application-rb"><tt>railties/lib/rails/application.rb</tt></a></li> <li><a href="#active_support-file_update_checker-rb"><tt>active_support/file_update_checker.rb</tt></a></li> <li><a href="#railties-lib-rails-plugin-rb"><tt>railties/lib/rails/plugin.rb</tt></a></li> <li><a href="#railties-lib-rails-engine-rb"><tt>railties/lib/rails/engine.rb</tt></a></li> <li><a href="#railties-lib-rails-railtie-rb"><tt>railties/lib/rails/railtie.rb</tt></a></li> <li><a href="#railties-lib-rails-initializable-rb"><tt>railties/lib/rails/initializable.rb</tt></a></li> <li><a href="#railties-lib-rails-configuration-rb"><tt>railties/lib/rails/configuration.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-deprecation-rb"><tt>activesupport/lib/active_support/deprecation.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-deprecation-behaviors-rb"><tt>activesupport/lib/active_support/deprecation/behaviors.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-notifications-rb"><tt>activesupport/lib/active_support/notifications.rb</tt></a></li> <li><a href="#activesupport-core_ext-array-wrap"><tt>activesupport/core_ext/array/wrap</tt></a></li> <li><a href="#activesupport-lib-active_support-deprecation-reporting-rb"><tt>activesupport/lib/active_support/deprecation/reporting.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-deprecation-method_wrappers-rb"><tt>activesupport/lib/active_support/deprecation/method_wrappers.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-deprecation-proxy_wrappers-rb"><tt>activesupport/lib/active_support/deprecation/proxy_wrappers.rb</tt></a></li> <li><a href="#active_support-ordered_options"><tt>active_support/ordered_options</tt></a></li> <li><a href="#railties-lib-rails-paths-rb"><tt>railties/lib/rails/paths.rb</tt></a></li> <li><a href="#railties-lib-rails-rack-rb"><tt>railties/lib/rails/rack.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-inflector-rb"><tt>activesupport/lib/active_support/inflector.rb</tt></a></li> <li><a href="#active_support-inflections"><tt>active_support/inflections</tt></a></li> <li><a href="#activesupport-lib-active_support-inflector-transliterate-rb"><tt>activesupport/lib/active_support/inflector/transliterate.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-railtie-rb">Back to <tt>railties/lib/rails/railtie.rb</tt></a></li> <li><a href="#railties-lib-rails-engine-railties-rb"><tt>railties/lib/rails/engine/railties.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-engine-rb">Back to <tt>railties/lib/rails/engine.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-plugin-rb">Back to <tt>railties/lib/rails/plugin.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-application-rb">Back to <tt>railties/lib/rails/application.rb</tt></a></li> <li><a href="#railties-lib-rails-version-rb"><tt>railties/lib/rails/version.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-railtie-rb"><tt>activesupport/lib/active_support/railtie.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-i18n_railtie-rb"><tt>activesupport/lib/active_support/i18n_railtie.rb</tt></a></li> <li><a href="#railties-lib-rails-railtie-configuration-rb"><tt>railties/lib/rails/railtie/configuration.rb</tt></a></li> <li><a href="#back-to-activesupport-lib-active_support-i18n_railtie-rb">Back to <tt>activesupport/lib/active_support/i18n_railtie.rb</tt></a></li> <li><a href="#back-to-activesupport-lib-active_support-railtie-rb">Back to <tt>activesupport/lib/active_support/railtie.rb</tt></a></li> <li><a href="#activesupport-lib-action_dispatch-railtie-rb"><tt>activesupport/lib/action_dispatch/railtie.rb</tt></a></li> <li><a href="#activesupport-lib-action_dispatch-rb"><tt>activesupport/lib/action_dispatch.rb</tt></a></li> <li><a href="#activemodel-lib-active_model-rb"><tt>activemodel/lib/active_model.rb</tt></a></li> <li><a href="#activesupport-lib-active_support-i18n-rb"><tt>activesupport/lib/active_support/i18n.rb</tt></a></li> <li><a href="#back-to-activesupport-lib-action_dispatch-rb">Back to <tt>activesupport/lib/action_dispatch.rb</tt></a></li> <li><a href="#back-to-activesupport-lib-action_dispatch-railtie-rb">Back to <tt>activesupport/lib/action_dispatch/railtie.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-rb">Back to <tt>railties/lib/rails.rb</tt></a></li> <li><a href="#back-to-railties-lib-rails-all-rb">Back to <tt>railties/lib/rails/all.rb</tt></a></li> <li><a href="#activerecord-lib-active_record-railtie-rb"><tt>activerecord/lib/active_record/railtie.rb</tt></a></li> <li><a href="#activerecord-lib-active_record-rb"><tt>activerecord/lib/active_record.rb</tt></a></li> <li><a href="#back-to-activerecord-lib-active_record-railtie-rb">Back to <tt>activerecord/lib/active_record/railtie.rb</tt></a></li> <li><a href="#actionpack-lib-action_controller-railtie-rb"><tt>actionpack/lib/action_controller/railtie.rb</tt></a></li> <li><a href="#actionpack-lib-action_view-rb"><tt>actionpack/lib/action_view.rb</tt></a></li></ul></li></ol></div>
|
109
|
+
</div>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
<div id="container">
|
113
|
+
<div class="wrapper">
|
114
|
+
<div id="mainCol">
|
115
|
+
<p>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 (<tt>rails server</tt> and Passenger) boot a Rails application.</p>
|
116
|
+
<div class="note"><p>Paths in this guide are relative to Rails or a Rails application unless otherwise specified.</p></div>
|
117
|
+
<h3 id="launch">1 Launch!</h3>
|
118
|
+
<p>As of Rails 3, <tt>script/server</tt> has become <tt>rails server</tt>. This was done to centralize all rails related commands to one common file.</p>
|
119
|
+
<h4 id="bin-rails">1.1 <tt>bin/rails</tt></h4>
|
120
|
+
<p>The actual <tt>rails</tt> command is kept in <em>bin/rails</em> at the and goes like this:</p>
|
121
|
+
<div class="code_container">
|
122
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
123
|
+
#!/usr/bin/env ruby
|
124
|
+
|
125
|
+
begin
|
126
|
+
require "rails/cli"
|
127
|
+
rescue LoadError
|
128
|
+
railties_path = File.expand_path('../../railties/lib', __FILE__)
|
129
|
+
$:.unshift(railties_path)
|
130
|
+
require "rails/cli"
|
131
|
+
end
|
132
|
+
</pre>
|
133
|
+
</div>
|
134
|
+
<p>This file will attempt to load <tt>rails/cli</tt> and if it cannot find it then add the <tt>railties/lib</tt> path to the load path (<tt>$:</tt>) and will then try to require it again.</p>
|
135
|
+
<h4 id="railties-lib-rails-cli-rb">1.2 <tt>railties/lib/rails/cli.rb</tt></h4>
|
136
|
+
<p>This file looks like this:</p>
|
137
|
+
<div class="code_container">
|
138
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
139
|
+
require 'rbconfig'
|
140
|
+
require 'rails/script_rails_loader'
|
141
|
+
|
142
|
+
# If we are inside a Rails application this method performs an exec and thus
|
143
|
+
# the rest of this script is not run.
|
144
|
+
Rails::ScriptRailsLoader.exec_script_rails!
|
145
|
+
|
146
|
+
require 'rails/ruby_version_check'
|
147
|
+
Signal.trap("INT") { puts; exit }
|
148
|
+
|
149
|
+
if ARGV.first == 'plugin'
|
150
|
+
ARGV.shift
|
151
|
+
require 'rails/commands/plugin_new'
|
152
|
+
else
|
153
|
+
require 'rails/commands/application'
|
154
|
+
end
|
155
|
+
</pre>
|
156
|
+
</div>
|
157
|
+
<p>The <tt>rbconfig</tt> file here is out of Ruby’s standard library and provides us with the <tt>RbConfig</tt> class which contains useful information dependent on how Ruby was compiled. We’ll see this in use in <tt>railties/lib/rails/script_rails_loader</tt>.</p>
|
158
|
+
<div class="code_container">
|
159
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
160
|
+
require 'pathname'
|
161
|
+
|
162
|
+
module Rails
|
163
|
+
module ScriptRailsLoader
|
164
|
+
RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
|
165
|
+
SCRIPT_RAILS = File.join('script', 'rails')
|
166
|
+
...
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
</pre>
|
171
|
+
</div>
|
172
|
+
<p>The <tt>rails/script_rails_loader</tt> file uses <tt>RbConfig::Config</tt> to gather up the <tt>bin_dir</tt> and <tt>ruby_install_name</tt> values for the configuration which will result in a path such as <tt>/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</tt>, which is the default path on Mac OS X. If you’re running Windows the path may be something such as <tt>C:/Ruby192/bin/ruby</tt>. Anyway, the path on your system may be different, but the point of this is that it will point at the known ruby executable location for your install. The <tt>RbConfig::CONFIG["EXEEXT"]</tt> will suffix this path with “.exe” if the script is running on Windows. This constant is used later on in <tt>exec_script_rails!</tt>. As for the <tt>SCRIPT_RAILS</tt> constant, we’ll see that when we get to the <tt>in_rails_application?</tt> method.</p>
|
173
|
+
<p>Back in <tt>rails/cli</tt>, the next line is this:</p>
|
174
|
+
<div class="code_container">
|
175
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
176
|
+
Rails::ScriptRailsLoader.exec_script_rails!
|
177
|
+
</pre>
|
178
|
+
</div>
|
179
|
+
<p>This method is defined in <tt>rails/script_rails_loader</tt> like this:</p>
|
180
|
+
<div class="code_container">
|
181
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
182
|
+
def self.exec_script_rails!
|
183
|
+
cwd = Dir.pwd
|
184
|
+
return unless in_rails_application? || in_rails_application_subdirectory?
|
185
|
+
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
|
186
|
+
Dir.chdir("..") do
|
187
|
+
# Recurse in a chdir block: if the search fails we want to be sure
|
188
|
+
# the application is generated in the original working directory.
|
189
|
+
exec_script_rails! unless cwd == Dir.pwd
|
190
|
+
end
|
191
|
+
rescue SystemCallError
|
192
|
+
# could not chdir, no problem just return
|
193
|
+
end
|
194
|
+
</pre>
|
195
|
+
</div>
|
196
|
+
<p>This method will first check if the current working directory (<tt>cwd</tt>) is a Rails application or is a subdirectory of one. The way to determine this is defined in the <tt>in_rails_application?</tt> method like this:</p>
|
197
|
+
<div class="code_container">
|
198
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
199
|
+
def self.in_rails_application?
|
200
|
+
File.exists?(SCRIPT_RAILS)
|
201
|
+
end
|
202
|
+
</pre>
|
203
|
+
</div>
|
204
|
+
<p>The <tt>SCRIPT_RAILS</tt> constant defined earlier is used here, with <tt>File.exists?</tt> checking for its presence in the current directory. If this method returns <tt>false</tt>, then <tt>in_rails_application_subdirectory?</tt> will be used:</p>
|
205
|
+
<div class="code_container">
|
206
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
207
|
+
def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
|
208
|
+
File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent)
|
209
|
+
end
|
210
|
+
</pre>
|
211
|
+
</div>
|
212
|
+
<p>This climbs the directory tree until it reaches a path which contains a <tt>script/rails</tt> file. If a directory is reached which contains this file then this line will run:</p>
|
213
|
+
<div class="code_container">
|
214
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
215
|
+
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
|
216
|
+
</pre>
|
217
|
+
</div>
|
218
|
+
<p>This is effectively the same as doing <tt>ruby script/rails [arguments]</tt>. Where <tt>[arguments]</tt> at this point in time is simply “server”.</p>
|
219
|
+
<h4 id="script-rails">1.3 <tt>script/rails</tt></h4>
|
220
|
+
<p>This file looks like this:</p>
|
221
|
+
<div class="code_container">
|
222
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
223
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
224
|
+
require File.expand_path('../../config/boot', __FILE__)
|
225
|
+
require 'rails/commands'
|
226
|
+
</pre>
|
227
|
+
</div>
|
228
|
+
<p>The <tt>APP_PATH</tt> constant here will be used later in <tt>rails/commands</tt>. The <tt>config/boot</tt> file that <tt>script/rails</tt> references is the <tt>config/boot.rb</tt> file in our application which is responsible for loading Bundler and setting it up.</p>
|
229
|
+
<h4 id="config-boot-rb">1.4 <tt>config/boot.rb</tt></h4>
|
230
|
+
<p><tt>config/boot.rb</tt> contains this:</p>
|
231
|
+
<div class="code_container">
|
232
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
233
|
+
require 'rubygems'
|
234
|
+
|
235
|
+
# Set up gems listed in the Gemfile.
|
236
|
+
gemfile = File.expand_path('../../Gemfile', __FILE__)
|
237
|
+
begin
|
238
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
239
|
+
require 'bundler'
|
240
|
+
Bundler.setup
|
241
|
+
rescue Bundler::GemNotFound => e
|
242
|
+
STDERR.puts e.message
|
243
|
+
STDERR.puts "Try running `bundle install`."
|
244
|
+
exit!
|
245
|
+
end if File.exist?(gemfile)
|
246
|
+
</pre>
|
247
|
+
</div>
|
248
|
+
<p>In a standard Rails application, there’s a <tt>Gemfile</tt> which declares all dependencies of the application. <tt>config/boot.rb</tt> sets <tt>ENV["BUNDLE_GEMFILE"]</tt> to the location of this file, then requires Bundler and calls <tt>Bundler.setup</tt> 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:</p>
|
249
|
+
<ul>
|
250
|
+
<li>abstract (1.0.0)</li>
|
251
|
+
<li>actionmailer (3.1.0.beta)</li>
|
252
|
+
<li>actionpack (3.1.0.beta)</li>
|
253
|
+
<li>activemodel (3.1.0.beta)</li>
|
254
|
+
<li>activerecord (3.1.0.beta)</li>
|
255
|
+
<li>activeresource (3.1.0.beta)</li>
|
256
|
+
<li>activesupport (3.1.0.beta)</li>
|
257
|
+
<li>arel (2.0.7)</li>
|
258
|
+
<li>builder (3.0.0)</li>
|
259
|
+
<li>bundler (1.0.6)</li>
|
260
|
+
<li>erubis (2.6.6)</li>
|
261
|
+
<li>i18n (0.5.0)</li>
|
262
|
+
<li>mail (2.2.12)</li>
|
263
|
+
<li>mime-types (1.16)</li>
|
264
|
+
<li>polyglot (0.3.1)</li>
|
265
|
+
<li>rack (1.2.1)</li>
|
266
|
+
<li>rack-cache (0.5.3)</li>
|
267
|
+
<li>rack-mount (0.6.13)</li>
|
268
|
+
<li>rack-test (0.5.6)</li>
|
269
|
+
<li>rails (3.1.0.beta)</li>
|
270
|
+
<li>railties (3.1.0.beta)</li>
|
271
|
+
<li>rake (0.8.7)</li>
|
272
|
+
<li>sqlite3-ruby (1.3.2)</li>
|
273
|
+
<li>thor (0.14.6)</li>
|
274
|
+
<li>treetop (1.4.9)</li>
|
275
|
+
<li>tzinfo (0.3.23)</li>
|
276
|
+
</ul>
|
277
|
+
<h4 id="rails-commands-rb">1.5 <tt>rails/commands.rb</tt></h4>
|
278
|
+
<p>Once <tt>config/boot.rb</tt> has finished, the next file that is required is <tt>rails/commands</tt> which will execute a command based on the arguments passed in. In this case, the <tt>ARGV</tt> array simply contains <tt>server</tt> which is extracted into the <tt>command</tt> variable using these lines:</p>
|
279
|
+
<div class="code_container">
|
280
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
281
|
+
aliases = {
|
282
|
+
"g" => "generate",
|
283
|
+
"c" => "console",
|
284
|
+
"s" => "server",
|
285
|
+
"db" => "dbconsole",
|
286
|
+
"r" => "runner"
|
287
|
+
}
|
288
|
+
|
289
|
+
command = ARGV.shift
|
290
|
+
command = aliases[command] || command
|
291
|
+
</pre>
|
292
|
+
</div>
|
293
|
+
<p>If we used <tt>s</tt> rather than <tt>server</tt>, Rails will use the <tt>aliases</tt> defined in the file and match them to their respective commands. With the <tt>server</tt> command, Rails will run this code:</p>
|
294
|
+
<div class="code_container">
|
295
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
296
|
+
when 'server'
|
297
|
+
# Change to the application's path if there is no config.ru file in current dir.
|
298
|
+
# This allows us to run script/rails server from other directories, but still get
|
299
|
+
# the main config.ru and properly set the tmp directory.
|
300
|
+
Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
|
301
|
+
|
302
|
+
require 'rails/commands/server'
|
303
|
+
Rails::Server.new.tap { |server|
|
304
|
+
# We need to require application after the server sets environment,
|
305
|
+
# otherwise the --environment option given to the server won't propagate.
|
306
|
+
require APP_PATH
|
307
|
+
Dir.chdir(Rails.application.root)
|
308
|
+
server.start
|
309
|
+
}
|
310
|
+
</pre>
|
311
|
+
</div>
|
312
|
+
<p>This file will change into the root of the directory (a path two directories back from <tt>APP_PATH</tt> which points at <tt>config/application.rb</tt>), but only if the <tt>config.ru</tt> file isn’t found. This then requires <tt>rails/commands/server</tt> which requires <tt>action_dispatch</tt> and sets up the <tt>Rails::Server</tt> class.</p>
|
313
|
+
<h4 id="actionpack-lib-action_dispatch-rb">1.6 <tt>actionpack/lib/action_dispatch.rb</tt></h4>
|
314
|
+
<p>Action Dispatch is the routing component of the Rails framework. It depends on Active Support, <tt>actionpack/lib/action_pack.rb</tt> and <tt>Rack</tt> being available. The first thing required here is <tt>active_support</tt>.</p>
|
315
|
+
<h4 id="activesupport-lib-active_support-rb">1.7 <tt>activesupport/lib/active_support.rb</tt></h4>
|
316
|
+
<p>This file begins with requiring <tt>active_support/lib/active_support/dependencies/autoload.rb</tt> which redefines Ruby’s <tt>autoload</tt> method to have a little more extra behaviour especially in regards to eager autoloading. Eager autoloading is the loading of all required classes and will happen when the <tt>config.cache_classes</tt> setting is <tt>true</tt>. The required file also requires another file: <tt>active_support/lazy_load_hooks</tt></p>
|
317
|
+
<h4 id="activesupport-lib-active_support-lazy_load_hooks-rb">1.8 <tt>activesupport/lib/active_support/lazy_load_hooks.rb</tt></h4>
|
318
|
+
<p>This file defines the <tt>ActiveSupport.on_load</tt> hook which is used to execute code when specific parts are loaded. We’ll see this in use a little later on.</p>
|
319
|
+
<p>This file begins with requiring <tt>active_support/inflector/methods</tt>.</p>
|
320
|
+
<h4 id="activesupport-lib-active_support-inflector-methods-rb">1.9 <tt>activesupport/lib/active_support/inflector/methods.rb</tt></h4>
|
321
|
+
<p>The <tt>methods.rb</tt> file is responsible for defining methods such as <tt>camelize</tt>, <tt>underscore</tt> and <tt>dasherize</tt> as well as a slew of others. The <a href="http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html"><tt>ActiveSupport::Inflector</tt> documentation</a> covers them all pretty decently.</p>
|
322
|
+
<p>In this file there are a lot of lines such as this inside the <tt>ActiveSupport</tt> module:</p>
|
323
|
+
<div class="code_container">
|
324
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
325
|
+
autoload :Inflector
|
326
|
+
</pre>
|
327
|
+
</div>
|
328
|
+
<p>Due to the overriding of the <tt>autoload</tt> method, Ruby will know how to look for this file at <tt>activesupport/lib/active_support/inflector.rb</tt> when the <tt>Inflector</tt> class is first referenced.</p>
|
329
|
+
<p>The <tt>active_support/lib/active_support/version.rb</tt> that is also required here simply defines an <tt>ActiveSupport::VERSION</tt> constant which defines a couple of constants inside this module, the main constant of this is <tt>ActiveSupport::VERSION::STRING</tt> which returns the current version of ActiveSupport.</p>
|
330
|
+
<p>The <tt>active_support/lib/active_support.rb</tt> file simply defines the <tt>ActiveSupport</tt> module and some autoloads (eager and of the normal variety) for it.</p>
|
331
|
+
<h4 id="actionpack-lib-action_dispatch-rb-cont-d">1.10 <tt>actionpack/lib/action_dispatch.rb</tt> cont’d.</h4>
|
332
|
+
<p>Now back to <tt>action_pack/lib/action_dispatch.rb</tt>. The next <tt>require</tt> in this file is one for <tt>action_pack</tt>, which simply calls <tt>action_pack/version.rb</tt> which defines <tt>ActionPack::VERSION</tt> and the constants, much like <tt>ActiveSpport</tt> does.</p>
|
333
|
+
<p>After this line, there’s a require to <tt>active_model</tt> which simply defines autoloads for the <tt>ActiveModel</tt> part of Rails and sets up the <tt>ActiveModel</tt> module which is used later on.</p>
|
334
|
+
<p>The last of the requires is to <tt>rack</tt>, which like the <tt>active_model</tt> and <tt>active_support</tt> requires before it, sets up the <tt>Rack</tt> module as well as the autoloads for constants within it.</p>
|
335
|
+
<p>Finally in <tt>action_dispatch.rb</tt> the <tt>ActionDispatch</tt> module and <strong>its</strong> autoloads are declared.</p>
|
336
|
+
<h4 id="rails-commands-server-rb">1.11 <tt>rails/commands/server.rb</tt></h4>
|
337
|
+
<p>The <tt>Rails::Server</tt> class is defined in this file as inheriting from <tt>Rack::Server</tt>. When <tt>Rails::Server.new</tt> is called, this calls the <tt>initialize</tt> method in <tt>rails/commands/server.rb</tt>:</p>
|
338
|
+
<div class="code_container">
|
339
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
340
|
+
def initialize(*)
|
341
|
+
super
|
342
|
+
set_environment
|
343
|
+
end
|
344
|
+
</pre>
|
345
|
+
</div>
|
346
|
+
<p>Firstly, <tt>super</tt> is called which calls the <tt>initialize</tt> method on <tt>Rack::Server</tt>.</p>
|
347
|
+
<h4 id="rack-lib-rack-server-rb">1.12 Rack: <tt>lib/rack/server.rb</tt></h4>
|
348
|
+
<p><tt>Rack::Server</tt> is responsible for providing a common server interface for all Rack-based applications, which Rails is now a part of.</p>
|
349
|
+
<p>The <tt>initialize</tt> method in <tt>Rack::Server</tt> simply sets a couple of variables:</p>
|
350
|
+
<div class="code_container">
|
351
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
352
|
+
def initialize(options = nil)
|
353
|
+
@options = options
|
354
|
+
@app = options[:app] if options && options[:app]
|
355
|
+
end
|
356
|
+
</pre>
|
357
|
+
</div>
|
358
|
+
<p>In this case, <tt>options</tt> will be <tt>nil</tt> so nothing happens in this method.</p>
|
359
|
+
<p>After <tt>super</tt> has finished in <tt>Rack::Server</tt>, we jump back to <tt>rails/commands/server.rb</tt>. At this point, <tt>set_environment</tt> is called within the context of the <tt>Rails::Server</tt> object and this method doesn’t appear to do much at first glance:</p>
|
360
|
+
<div class="code_container">
|
361
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
362
|
+
def set_environment
|
363
|
+
ENV["RAILS_ENV"] ||= options[:environment]
|
364
|
+
end
|
365
|
+
</pre>
|
366
|
+
</div>
|
367
|
+
<p>In fact, the <tt>options</tt> method here does quite a lot. This method is defined in <tt>Rack::Server</tt> like this:</p>
|
368
|
+
<div class="code_container">
|
369
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
370
|
+
def options
|
371
|
+
@options ||= parse_options(ARGV)
|
372
|
+
end
|
373
|
+
</pre>
|
374
|
+
</div>
|
375
|
+
<p>Then <tt>parse_options</tt> is defined like this:</p>
|
376
|
+
<div class="code_container">
|
377
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
378
|
+
def parse_options(args)
|
379
|
+
options = default_options
|
380
|
+
|
381
|
+
# Don't evaluate CGI ISINDEX parameters.
|
382
|
+
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
|
383
|
+
args.clear if ENV.include?("REQUEST_METHOD")
|
384
|
+
|
385
|
+
options.merge! opt_parser.parse! args
|
386
|
+
options[:config] = ::File.expand_path(options[:config])
|
387
|
+
ENV["RACK_ENV"] = options[:environment]
|
388
|
+
options
|
389
|
+
end
|
390
|
+
</pre>
|
391
|
+
</div>
|
392
|
+
<p>With the <tt>default_options</tt> set to this:</p>
|
393
|
+
<div class="code_container">
|
394
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
395
|
+
def default_options
|
396
|
+
{
|
397
|
+
:environment => ENV['RACK_ENV'] || "development",
|
398
|
+
:pid => nil,
|
399
|
+
:Port => 9292,
|
400
|
+
:Host => "0.0.0.0",
|
401
|
+
:AccessLog => [],
|
402
|
+
:config => "config.ru"
|
403
|
+
}
|
404
|
+
end
|
405
|
+
</pre>
|
406
|
+
</div>
|
407
|
+
<p>There is no <tt>REQUEST_METHOD</tt> key in <tt>ENV</tt> so we can skip over that line. The next line merges in the options from <tt>opt_parser</tt> which is defined plainly in <tt>Rack::Server</tt></p>
|
408
|
+
<div class="code_container">
|
409
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
410
|
+
def opt_parser
|
411
|
+
Options.new
|
412
|
+
end
|
413
|
+
</pre>
|
414
|
+
</div>
|
415
|
+
<p>The class <strong>is</strong> defined in <tt>Rack::Server</tt>, but is overwritten in <tt>Rails::Server</tt> to take different arguments. Its <tt>parse!</tt> method begins like this:</p>
|
416
|
+
<div class="code_container">
|
417
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
418
|
+
def parse!(args)
|
419
|
+
args, options = args.dup, {}
|
420
|
+
|
421
|
+
opt_parser = OptionParser.new do |opts|
|
422
|
+
opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
|
423
|
+
opts.on("-p", "--port=port", Integer,
|
424
|
+
"Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
|
425
|
+
...
|
426
|
+
</pre>
|
427
|
+
</div>
|
428
|
+
<p>This method will set up keys for the <tt>options</tt> which Rails will then be able to use to determine how its server should run. After <tt>initialize</tt> has finished, then the <tt>start</tt> method will launch the server.</p>
|
429
|
+
<h4 id="rails-server-start">1.13 <tt>Rails::Server#start</tt></h4>
|
430
|
+
<p>This method is defined like this:</p>
|
431
|
+
<div class="code_container">
|
432
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
433
|
+
def start
|
434
|
+
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
|
435
|
+
puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
|
436
|
+
puts "=> Call with -d to detach" unless options[:daemonize]
|
437
|
+
trap(:INT) { exit }
|
438
|
+
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
|
439
|
+
|
440
|
+
#Create required tmp directories if not found
|
441
|
+
%w(cache pids sessions sockets).each do |dir_to_make|
|
442
|
+
FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
|
443
|
+
end
|
444
|
+
|
445
|
+
super
|
446
|
+
ensure
|
447
|
+
# The '-h' option calls exit before @options is set.
|
448
|
+
# If we call 'options' with it unset, we get double help banners.
|
449
|
+
puts 'Exiting' unless @options && options[:daemonize]
|
450
|
+
end
|
451
|
+
</pre>
|
452
|
+
</div>
|
453
|
+
<p>This is where the first output of the Rails initialization happens. This method creates a trap for <tt>INT</tt> signals, so if you <tt>CTRL</tt>C<tt> the server, it will exit the process. As we can see from the code here, it will create the </tt>tmp/cache<tt>, </tt>tmp/pids<tt>, </tt>tmp/sessions<tt> and </tt>tmp/sockets<tt> directories if they don't already exist prior to calling </tt>super<tt>. The </tt>super<tt> method will call </tt>Rack::Server.start+ which begins its definition like this:</p>
|
454
|
+
<div class="code_container">
|
455
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
456
|
+
def start
|
457
|
+
if options[:warn]
|
458
|
+
$-w = true
|
459
|
+
end
|
460
|
+
|
461
|
+
if includes = options[:include]
|
462
|
+
$LOAD_PATH.unshift(*includes)
|
463
|
+
end
|
464
|
+
|
465
|
+
if library = options[:require]
|
466
|
+
require library
|
467
|
+
end
|
468
|
+
|
469
|
+
if options[:debug]
|
470
|
+
$DEBUG = true
|
471
|
+
require 'pp'
|
472
|
+
p options[:server]
|
473
|
+
pp wrapped_app
|
474
|
+
pp app
|
475
|
+
end
|
476
|
+
end
|
477
|
+
</pre>
|
478
|
+
</div>
|
479
|
+
<p>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:</p>
|
480
|
+
<div class="code_container">
|
481
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
482
|
+
wrapped_app
|
483
|
+
</pre>
|
484
|
+
</div>
|
485
|
+
<p>This method calls another method:</p>
|
486
|
+
<div class="code_container">
|
487
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
488
|
+
@wrapped_app ||= build_app app
|
489
|
+
</pre>
|
490
|
+
</div>
|
491
|
+
<p>Then the <tt>app</tt> method here is defined like so:</p>
|
492
|
+
<div class="code_container">
|
493
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
494
|
+
def app
|
495
|
+
@app ||= begin
|
496
|
+
if !::File.exist? options[:config]
|
497
|
+
abort "configuration #{options[:config]} not found"
|
498
|
+
end
|
499
|
+
|
500
|
+
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
501
|
+
self.options.merge! options
|
502
|
+
app
|
503
|
+
end
|
504
|
+
end
|
505
|
+
</pre>
|
506
|
+
</div>
|
507
|
+
<p>The <tt>options[:config]</tt> value defaults to <tt>config.ru</tt> which contains this:</p>
|
508
|
+
<div class="code_container">
|
509
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
510
|
+
# This file is used by Rack-based servers to start the application.
|
511
|
+
|
512
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
513
|
+
run YourApp::Application
|
514
|
+
</pre>
|
515
|
+
</div>
|
516
|
+
<p>The <tt>Rack::Builder.parse_file</tt> method here takes the content from this <tt>config.ru</tt> file and parses it using this code:</p>
|
517
|
+
<div class="code_container">
|
518
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
519
|
+
app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
|
520
|
+
TOPLEVEL_BINDING, config
|
521
|
+
</pre>
|
522
|
+
</div>
|
523
|
+
<p>The <tt>initialize</tt> method will take the block here and execute it within an instance of <tt>Rack::Builder</tt>. This is where the majority of the initialization process of Rails happens. The chain of events that this simple line sets off will be the focus of a large majority of this guide. The <tt>require</tt> line for <tt>config/environment.rb</tt> in <tt>config.ru</tt> is the first to run:</p>
|
524
|
+
<div class="code_container">
|
525
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
526
|
+
require ::File.expand_path('../config/environment', __FILE__)
|
527
|
+
</pre>
|
528
|
+
</div>
|
529
|
+
<h4 id="config-environment-rb">1.14 <tt>config/environment.rb</tt></h4>
|
530
|
+
<p>This file is the common file required by <tt>config.ru</tt> (<tt>rails server</tt>) and Passenger. This is where these two ways to run the server meet; everything before this point has been Rack and Rails setup.</p>
|
531
|
+
<p>This file begins with requiring <tt>config/application.rb</tt>.</p>
|
532
|
+
<h4 id="config-application-rb">1.15 <tt>config/application.rb</tt></h4>
|
533
|
+
<p>This file requires <tt>config/boot.rb</tt>, but only if it hasn’t been required before, which would be the case in <tt>rails server</tt> but <strong>wouldn’t</strong> be the case with Passenger.</p>
|
534
|
+
<p>Then the fun begins!</p>
|
535
|
+
<h3 id="loading-rails">2 Loading Rails</h3>
|
536
|
+
<p>The next line in <tt>config/application.rb</tt> is:</p>
|
537
|
+
<div class="code_container">
|
538
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
539
|
+
require 'rails/all'
|
540
|
+
</pre>
|
541
|
+
</div>
|
542
|
+
<h4 id="railties-lib-rails-all-rb">2.1 <tt>railties/lib/rails/all.rb</tt></h4>
|
543
|
+
<p>This file is responsible for requiring all the individual parts of Rails like so:</p>
|
544
|
+
<div class="code_container">
|
545
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
546
|
+
require "rails"
|
547
|
+
|
548
|
+
%w(
|
549
|
+
active_record
|
550
|
+
action_controller
|
551
|
+
action_mailer
|
552
|
+
active_resource
|
553
|
+
rails/test_unit
|
554
|
+
).each do |framework|
|
555
|
+
begin
|
556
|
+
require "#{framework}/railtie"
|
557
|
+
rescue LoadError
|
558
|
+
end
|
559
|
+
end
|
560
|
+
</pre>
|
561
|
+
</div>
|
562
|
+
<p>First off the line is the <tt>rails</tt> require itself.</p>
|
563
|
+
<h4 id="railties-lib-rails-rb">2.2 <tt>railties/lib/rails.rb</tt></h4>
|
564
|
+
<p>This file is responsible for the initial definition of the <tt>Rails</tt> module and, rather than defining the autoloads like <tt>ActiveSupport</tt>, <tt>ActionDispatch</tt> and so on, it actually defines other functionality. Such as the <tt>root</tt>, <tt>env</tt> and <tt>application</tt> methods which are extremely useful in Rails 3 applications.</p>
|
565
|
+
<p>However, before all that takes place the <tt>rails/ruby_version_check</tt> file is required first.</p>
|
566
|
+
<h4 id="railties-lib-rails-ruby_version_check-rb">2.3 <tt>railties/lib/rails/ruby_version_check.rb</tt></h4>
|
567
|
+
<p>This file simply checks if the Ruby version is less than 1.8.7 or is 1.9.1 and raises an error if that is the case. Rails 3 simply will not run on earlier versions of Ruby than 1.8.7 or 1.9.1.</p>
|
568
|
+
<div class="note"><p>You should always endeavor to run the latest version of Ruby with your Rails applications. The benefits are many, including security fixes and the like, and very often there is a speed increase associated with it. The caveat is that you could have code that potentially breaks on the latest version, which should be fixed to work on the latest version rather than kept around as an excuse not to upgrade.</p></div>
|
569
|
+
<h4 id="active_support-core_ext-kernel-reporting-rb">2.4 <tt>active_support/core_ext/kernel/reporting.rb</tt></h4>
|
570
|
+
<p>This is the first of the many Active Support core extensions that come with Rails. This one in particular defines methods in the <tt>Kernel</tt> module which is mixed in to the <tt>Object</tt> class so the methods are available on <tt>main</tt> and can therefore be called like this:</p>
|
571
|
+
<div class="code_container">
|
572
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
573
|
+
silence_warnings do
|
574
|
+
# some code
|
575
|
+
end
|
576
|
+
</pre>
|
577
|
+
</div>
|
578
|
+
<p>These methods can be used to silence <span class="caps">STDERR</span> responses and the <tt>silence_stream</tt> allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions">Silencing Warnings, Streams, and Exceptions</a> section from the Active Support Core Extensions Guide.</p>
|
579
|
+
<h4 id="active_support-core_ext-logger-rb">2.5 <tt>active_support/core_ext/logger.rb</tt></h4>
|
580
|
+
<p>The next file that is required is another Active Support core extension, this time to the <tt>Logger</tt> class. This begins by defining the <tt>around_[level]</tt> helpers for the <tt>Logger</tt> class as well as other methods such as a <tt>datetime_format</tt> getter and setter for the <tt>formatter</tt> object tied to a <tt>Logger</tt> object.</p>
|
581
|
+
<p>For more information see the <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-logger">Extensions to Logger</a> section from the Active Support Core Extensions Guide.</p>
|
582
|
+
<h4 id="railties-lib-rails-application-rb">2.6 <tt>railties/lib/rails/application.rb</tt></h4>
|
583
|
+
<p>The next file required by <tt>railties/lib/rails.rb</tt> is <tt>application.rb</tt>. This file defines the <tt>Rails::Application</tt> constant which the application’s class defined in <tt>config/application.rb</tt> in a standard Rails application depends on. Before the <tt>Rails::Application</tt> class is defined however, there’s some other files that get required first.</p>
|
584
|
+
<p>The first of these is <tt>active_support/core_ext/hash/reverse_merge</tt> which can be <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#merging">read about in the Active Support Core Extensions guide</a> under the “Merging” section.</p>
|
585
|
+
<h4 id="active_support-file_update_checker-rb">2.7 <tt>active_support/file_update_checker.rb</tt></h4>
|
586
|
+
<p>The <tt>ActiveSupport::FileUpdateChecker</tt> class defined within this file is responsible for checking if a file has been updated since it was last checked. This is used for monitoring the routes file for changes during development environment runs.</p>
|
587
|
+
<h4 id="railties-lib-rails-plugin-rb">2.8 <tt>railties/lib/rails/plugin.rb</tt></h4>
|
588
|
+
<p>This file defines <tt>Rails::Plugin</tt> which inherits from <tt>Rails::Engine</tt>. Unlike <tt>Rails::Engine</tt> and <tt>Rails::Railtie</tt> however, this class is not designed to be inherited from. Instead, this is used simply for loading plugins from within an application and an engine.</p>
|
589
|
+
<p>This file begins by requiring <tt>rails/engine.rb</tt></p>
|
590
|
+
<h4 id="railties-lib-rails-engine-rb">2.9 <tt>railties/lib/rails/engine.rb</tt></h4>
|
591
|
+
<p>The <tt>rails/engine.rb</tt> file defines the <tt>Rails::Engine</tt> class which inherits from <tt>Rails::Railtie</tt>. The <tt>Rails::Engine</tt> class defines much of the functionality found within a standard application class such as the <tt>routes</tt> and <tt>config</tt> methods.</p>
|
592
|
+
<p>The <a href="http://api.rubyonrails.org/classes/Rails/Engine.html"><span class="caps">API</span> documentation</a> for <tt>Rails::Engine</tt> explains the function of this class pretty well.</p>
|
593
|
+
<p>This file’s first line requires <tt>rails/railtie.rb</tt>.</p>
|
594
|
+
<h4 id="railties-lib-rails-railtie-rb">2.10 <tt>railties/lib/rails/railtie.rb</tt></h4>
|
595
|
+
<p>The <tt>rails/railtie.rb</tt> file is responsible for defining <tt>Rails::Railtie</tt>, the underlying class for all ties to Rails now. Gems that want to have their own initializers or rake tasks and hook into Rails should have a <tt>GemName::Railtie</tt> class that inherits from <tt>Rails::Railtie</tt>.</p>
|
596
|
+
<p>The <a href="http://api.rubyonrails.org/classes/Rails/Railtie.html"><span class="caps">API</span> documentation</a> for <tt>Rails::Railtie</tt>, much like <tt>Rails::Engine</tt>, explains this class exceptionally well.</p>
|
597
|
+
<p>The first require in this file is <tt>rails/initializable.rb</tt>.</p>
|
598
|
+
<h4 id="railties-lib-rails-initializable-rb">2.11 <tt>railties/lib/rails/initializable.rb</tt></h4>
|
599
|
+
<p>Now we reach the end of this particular rabbit hole as <tt>rails/initializable.rb</tt> doesn’t require any more Rails files, only <tt>tsort</tt> from the Ruby standard library.</p>
|
600
|
+
<p>This file defines the <tt>Rails::Initializable</tt> module which contains the <tt>Initializer</tt> class, the basis for all initializers in Rails. This module also contains a <tt>ClassMethods</tt> class which will be included into the <tt>Rails::Railtie</tt> class when these requires have finished.</p>
|
601
|
+
<p>Now that <tt>rails/initializable.rb</tt> has finished being required from <tt>rails/railtie.rb</tt>, the next require is for <tt>rails/configuration</tt>.</p>
|
602
|
+
<h4 id="railties-lib-rails-configuration-rb">2.12 <tt>railties/lib/rails/configuration.rb</tt></h4>
|
603
|
+
<p>This file defines the <tt>Rails::Configuration</tt> module, containing the <tt>MiddlewareStackProxy</tt> class as well as the <tt>Generators</tt> class. The <tt>MiddlewareStackProxy</tt> class is used for managing the middleware stack for an application, which we’ll see later on. The <tt>Generators</tt> class provides the functionality used for configuring what generators an application uses through the <a href="http://guides.rubyonrails.org/configuring.html#configuring-generators"><tt>config.generators</tt> option</a>.</p>
|
604
|
+
<p>The first file required in this file is <tt>activesupport/deprecation</tt>.</p>
|
605
|
+
<h4 id="activesupport-lib-active_support-deprecation-rb">2.13 <tt>activesupport/lib/active_support/deprecation.rb</tt></h4>
|
606
|
+
<p>This file, and the files it requires, define the basic deprecation warning features found in Rails. This file is responsible for setting defaults in the <tt>ActiveSupport::Deprecation</tt> module for the <tt>deprecation_horizon</tt>, <tt>silenced</tt> and <tt>debug</tt> values. The files that are required before this happens are:</p>
|
607
|
+
<ul>
|
608
|
+
<li><tt>active_support/deprecation/behaviors</tt></li>
|
609
|
+
<li><tt>active_support/deprecation/reporting</tt></li>
|
610
|
+
<li><tt>active_support/deprecation/method_wrappers</tt></li>
|
611
|
+
<li><tt>active_support/deprecation/proxy_wrappers</tt></li>
|
612
|
+
</ul>
|
613
|
+
<h4 id="activesupport-lib-active_support-deprecation-behaviors-rb">2.14 <tt>activesupport/lib/active_support/deprecation/behaviors.rb</tt></h4>
|
614
|
+
<p>This file defines the behavior of the <tt>ActiveSupport::Deprecation</tt> module, setting up the <tt>DEFAULT_BEHAVIORS</tt> hash constant which contains the three defaults to outputting deprecation warnings: <tt>:stderr</tt>, <tt>:log</tt> and <tt>:notify</tt>. This file begins by requiring <tt>activesupport/notifications</tt> and <tt>activesupport/core_ext/array/wrap</tt>.</p>
|
615
|
+
<h4 id="activesupport-lib-active_support-notifications-rb">2.15 <tt>activesupport/lib/active_support/notifications.rb</tt></h4>
|
616
|
+
<p>This file defines the <tt>ActiveSupport::Notifications</tt> module. Notifications provides an instrumentation <span class="caps">API</span> for Ruby, shipping with a queue implementation that consumes and publish events to log subscribers in a thread.</p>
|
617
|
+
<p>The <a href="http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html"><span class="caps">API</span> documentation</a> for <tt>ActiveSupport::Notifications</tt> explains the usage of this module, including the methods that it defines.</p>
|
618
|
+
<p>The file required in <tt>active_support/notifications.rb</tt> is <tt>active_support/core_ext/module/delegation</tt> which is documented in the <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation">Active Support Core Extensions Guide</a>.</p>
|
619
|
+
<h4 id="activesupport-core_ext-array-wrap">2.16 <tt>activesupport/core_ext/array/wrap</tt></h4>
|
620
|
+
<p>As this file comprises of a core extension, it is covered exclusively in <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#wrapping">the Active Support Core Extensions guide</a></p>
|
621
|
+
<h4 id="activesupport-lib-active_support-deprecation-reporting-rb">2.17 <tt>activesupport/lib/active_support/deprecation/reporting.rb</tt></h4>
|
622
|
+
<p>This file is responsible for defining the <tt>warn</tt> and <tt>silence</tt> methods for <tt>ActiveSupport::Deprecation</tt> as well as additional private methods for this module.</p>
|
623
|
+
<h4 id="activesupport-lib-active_support-deprecation-method_wrappers-rb">2.18 <tt>activesupport/lib/active_support/deprecation/method_wrappers.rb</tt></h4>
|
624
|
+
<p>This file defines a <tt>deprecate_methods</tt> which is primarily used by the <tt>module/deprecation</tt> core extension required by the first line of this file. Other core extensions required by this file are the <tt>module/aliasing</tt> and <tt>array/extract_options</tt> files.</p>
|
625
|
+
<h4 id="activesupport-lib-active_support-deprecation-proxy_wrappers-rb">2.19 <tt>activesupport/lib/active_support/deprecation/proxy_wrappers.rb</tt></h4>
|
626
|
+
<p><tt>proxy_wrappers.rb</tt> defines deprecation wrappers for methods, instance variables and constants. Previously, this was used for the <tt>RAILS_ENV</tt> and <tt>RAILS_ROOT</tt> constants for 3.0 but since then these constants have been removed. The deprecation message that would be raised from these would be something like:</p>
|
627
|
+
<div class="code_container">
|
628
|
+
<pre class="brush: plain; gutter: false; toolbar: false">
|
629
|
+
BadConstant is deprecated! Use GoodConstant instead.
|
630
|
+
</pre>
|
631
|
+
</div>
|
632
|
+
<h4 id="active_support-ordered_options">2.20 <tt>active_support/ordered_options</tt></h4>
|
633
|
+
<p>This file is the next file required from <tt>rails/configuration.rb</tt> is the file that defines <tt>ActiveSupport::OrderedOptions</tt> which is used for configuration options such as <tt>config.active_support</tt> and the like.</p>
|
634
|
+
<p>The next file required is <tt>active_support/core_ext/hash/deep_dup</tt> which is covered in <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#deep_dup">Active Support Core Extensions guide</a></p>
|
635
|
+
<p>The file that is required next from is <tt>rails/paths</tt></p>
|
636
|
+
<h4 id="railties-lib-rails-paths-rb">2.21 <tt>railties/lib/rails/paths.rb</tt></h4>
|
637
|
+
<p>This file defines the <tt>Rails::Paths</tt> module which allows paths to be configured for a Rails application or engine. Later on in this guide when we cover Rails configuration during the initialization process we’ll see this used to set up some default paths for Rails and some of them will be configured to be eager loaded.</p>
|
638
|
+
<h4 id="railties-lib-rails-rack-rb">2.22 <tt>railties/lib/rails/rack.rb</tt></h4>
|
639
|
+
<p>The final file to be loaded by <tt>railties/lib/rails/configuration.rb</tt> is <tt>rails/rack</tt> which defines some simple autoloads:</p>
|
640
|
+
<div class="code_container">
|
641
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
642
|
+
module Rails
|
643
|
+
module Rack
|
644
|
+
autoload :Debugger, "rails/rack/debugger"
|
645
|
+
autoload :Logger, "rails/rack/logger"
|
646
|
+
autoload :LogTailer, "rails/rack/log_tailer"
|
647
|
+
autoload :Static, "rails/rack/static"
|
648
|
+
end
|
649
|
+
end
|
650
|
+
</pre>
|
651
|
+
</div>
|
652
|
+
<p>Once this file is finished loading, then the <tt>Rails::Configuration</tt> class is initialized. This completes the loading of <tt>railties/lib/rails/configuration.rb</tt> and now we jump back to the loading of <tt>railties/lib/rails/railtie.rb</tt>, where the next file loaded is <tt>active_support/inflector</tt>.</p>
|
653
|
+
<h4 id="activesupport-lib-active_support-inflector-rb">2.23 <tt>activesupport/lib/active_support/inflector.rb</tt></h4>
|
654
|
+
<p><tt>active_support/inflector.rb</tt> requires a series of file which are responsible for setting up the basics for knowing how to pluralize and singularize words. These files are:</p>
|
655
|
+
<div class="code_container">
|
656
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
657
|
+
require 'active_support/inflector/inflections'
|
658
|
+
require 'active_support/inflector/transliterate'
|
659
|
+
require 'active_support/inflector/methods'
|
660
|
+
|
661
|
+
require 'active_support/inflections'
|
662
|
+
require 'active_support/core_ext/string/inflections'
|
663
|
+
</pre>
|
664
|
+
</div>
|
665
|
+
<p>The <tt>active_support/inflector/methods</tt> file has already been required by <tt>active_support/autoload</tt> and so won’t be loaded again here. The <tt>activesupport/lib/active_support/inflector/inflections.rb</tt> is required by <tt>active_support/inflector/methods</tt>.</p>
|
666
|
+
<h4 id="active_support-inflections">2.24 <tt>active_support/inflections</tt></h4>
|
667
|
+
<p>This file references the <tt>ActiveSupport::Inflector</tt> constant which isn’t loaded by this point. But there were autoloads set up in <tt>activesupport/lib/active_support.rb</tt> which will load the file which loads this constant and so then it will be defined. Then this file defines pluralization and singularization rules for words in Rails. This is how Rails knows how to pluralize “tomato” to “tomatoes”.</p>
|
668
|
+
<h4 id="activesupport-lib-active_support-inflector-transliterate-rb">2.25 <tt>activesupport/lib/active_support/inflector/transliterate.rb</tt></h4>
|
669
|
+
<p>In this file is where the <a href="http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate"><tt>transliterate</tt></a> and <tt>parameterize</tt>:http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize methods are defined. The documentation for both of these methods is very much worth reading.</p>
|
670
|
+
<h4 id="back-to-railties-lib-rails-railtie-rb">2.26 Back to <tt>railties/lib/rails/railtie.rb</tt></h4>
|
671
|
+
<p>Once the inflector files have been loaded, the <tt>Rails::Railtie</tt> class is defined. This class includes a module called <tt>Initializable</tt>, which is actually <tt>Rails::Initializable</tt>. This module includes the <tt>initializer</tt> method which is used later on for setting up initializers, amongst other methods.</p>
|
672
|
+
<h4 id="railties-lib-rails-initializable-rb">2.27 <tt>railties/lib/rails/initializable.rb</tt></h4>
|
673
|
+
<p>When the module from this file (<tt>Rails::Initializable</tt>) is included, it extends the class it’s included into with the <tt>ClassMethods</tt> module inside of it. This module defines the <tt>initializer</tt> method which is used to define initializers throughout all of the railties. This file completes the loading of <tt>railties/lib/rails/railtie.rb</tt>. Now we go back to <tt>rails/engine.rb</tt>.</p>
|
674
|
+
<h4 id="railties-lib-rails-engine-rb">2.28 <tt>railties/lib/rails/engine.rb</tt></h4>
|
675
|
+
<p>The next file required in <tt>rails/engine.rb</tt> is <tt>active_support/core_ext/module/delegation</tt> which is documented in the <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#method-delegation">Active Support Core Extensions Guide</a>.</p>
|
676
|
+
<p>The next two files after this are Ruby standard library files: <tt>pathname</tt> and <tt>rbconfig</tt>. The file after these is <tt>rails/engine/railties</tt>.</p>
|
677
|
+
<h4 id="railties-lib-rails-engine-railties-rb">2.29 <tt>railties/lib/rails/engine/railties.rb</tt></h4>
|
678
|
+
<p>This file defines the <tt>Rails::Engine::Railties</tt> class which provides the <tt>engines</tt> and <tt>railties</tt> methods which are used later on for defining rake tasks and other functionality for engines and railties.</p>
|
679
|
+
<h4 id="back-to-railties-lib-rails-engine-rb">2.30 Back to <tt>railties/lib/rails/engine.rb</tt></h4>
|
680
|
+
<p>Once <tt>rails/engine/railties.rb</tt> has finished loading the <tt>Rails::Engine</tt> class gets its basic functionality defined, such as the <tt>inherited</tt> method which will be called when this class is inherited from.</p>
|
681
|
+
<p>Once this file has finished loading we jump back to <tt>railties/lib/rails/plugin.rb</tt></p>
|
682
|
+
<h4 id="back-to-railties-lib-rails-plugin-rb">2.31 Back to <tt>railties/lib/rails/plugin.rb</tt></h4>
|
683
|
+
<p>The next file required in this is a core extension from Active Support called <tt>array/conversions</tt> which is covered in <a href="http://guides.rubyonrails.org/active_support_core_extensions.html#array-conversions">this section</a> of the Active Support Core Extensions Guide.</p>
|
684
|
+
<p>Once that file has finished loading, the <tt>Rails::Plugin</tt> class is defined.</p>
|
685
|
+
<h4 id="back-to-railties-lib-rails-application-rb">2.32 Back to <tt>railties/lib/rails/application.rb</tt></h4>
|
686
|
+
<p>Jumping back to <tt>rails/application.rb</tt> now. This file defines the <tt>Rails::Application</tt> class where the application’s class inherits from. This class (and its superclasses) define the basic behaviour on the application’s constant such as the <tt>config</tt> method used for configuring the application.</p>
|
687
|
+
<p>Once this file’s done then we go back to the <tt>railties/lib/rails.rb</tt> file, which next requires <tt>rails/version</tt>.</p>
|
688
|
+
<h4 id="railties-lib-rails-version-rb">2.33 <tt>railties/lib/rails/version.rb</tt></h4>
|
689
|
+
<p>Much like <tt>active_support/version</tt>, this file defines the <tt>VERSION</tt> constant which has a <tt>STRING</tt> constant on it which returns the current version of Rails.</p>
|
690
|
+
<p>Once this file has finished loading we go back to <tt>railties/lib/rails.rb</tt> which then requires <tt>active_support/railtie.rb</tt>.</p>
|
691
|
+
<h4 id="activesupport-lib-active_support-railtie-rb">2.34 <tt>activesupport/lib/active_support/railtie.rb</tt></h4>
|
692
|
+
<p>This file requires <tt>active_support</tt> and <tt>rails</tt> which have already been required so these two lines are effectively ignored. The third require in this file is to <tt>active_support/i18n_railtie.rb</tt>.</p>
|
693
|
+
<h4 id="activesupport-lib-active_support-i18n_railtie-rb">2.35 <tt>activesupport/lib/active_support/i18n_railtie.rb</tt></h4>
|
694
|
+
<p>This file is the first file that sets up configuration with these lines inside the class:</p>
|
695
|
+
<div class="code_container">
|
696
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
697
|
+
class Railtie < Rails::Railtie
|
698
|
+
config.i18n = ActiveSupport::OrderedOptions.new
|
699
|
+
config.i18n.railties_load_path = []
|
700
|
+
config.i18n.load_path = []
|
701
|
+
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
702
|
+
</pre>
|
703
|
+
</div>
|
704
|
+
<p>By inheriting from <tt>Rails::Railtie</tt> the <tt>Rails::Railtie#inherited</tt> method is called:</p>
|
705
|
+
<div class="code_container">
|
706
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
707
|
+
def inherited(base)
|
708
|
+
unless base.abstract_railtie?
|
709
|
+
base.send(:include, Railtie::Configurable)
|
710
|
+
subclasses << base
|
711
|
+
end
|
712
|
+
end
|
713
|
+
</pre>
|
714
|
+
</div>
|
715
|
+
<p>This first checks if the Railtie that’s inheriting it is a component of Rails itself:</p>
|
716
|
+
<div class="code_container">
|
717
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
718
|
+
ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Plugin Rails::Engine Rails::Application)
|
719
|
+
|
720
|
+
...
|
721
|
+
|
722
|
+
def abstract_railtie?
|
723
|
+
ABSTRACT_RAILTIES.include?(name)
|
724
|
+
end
|
725
|
+
</pre>
|
726
|
+
</div>
|
727
|
+
<p>Because <tt>I18n::Railtie</tt> isn’t in this list, <tt>abstract_railtie?</tt> returns <tt>false</tt>. Therefore the <tt>Railtie::Configurable</tt> module is included into this class and the <tt>subclasses</tt> method is called and <tt>I18n::Railtie</tt> is added to this new array.</p>
|
728
|
+
<div class="code_container">
|
729
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
730
|
+
def subclasses
|
731
|
+
@subclasses ||= []
|
732
|
+
end
|
733
|
+
</pre>
|
734
|
+
</div>
|
735
|
+
<p>The <tt>config</tt> method used at the top of <tt>I18n::Railtie</tt> is defined on <tt>Rails::Railtie</tt> and is defined like this:</p>
|
736
|
+
<div class="code_container">
|
737
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
738
|
+
def config
|
739
|
+
@config ||= Railtie::Configuration.new
|
740
|
+
end
|
741
|
+
</pre>
|
742
|
+
</div>
|
743
|
+
<p>At this point, that <tt>Railtie::Configuration</tt> constant is automatically loaded which causes the <tt>rails/railties/configuration</tt> file to be loaded. The line for this is this particular line in <tt>railties/lib/rails/railtie.rb</tt>:</p>
|
744
|
+
<div class="code_container">
|
745
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
746
|
+
autoload :Configuration, "rails/railtie/configuration"
|
747
|
+
</pre>
|
748
|
+
</div>
|
749
|
+
<h4 id="railties-lib-rails-railtie-configuration-rb">2.36 <tt>railties/lib/rails/railtie/configuration.rb</tt></h4>
|
750
|
+
<p>This file begins with a require out to <tt>rails/configuration</tt> which has already been required earlier in the process and so isn’t required again.</p>
|
751
|
+
<p>This file defines the <tt>Rails::Railtie::Configuration</tt> class which is responsible for providing a way to easily configure railties and it’s the <tt>initialize</tt> method here which is called by the <tt>config</tt> method back in the <tt>i18n_railtie.rb</tt> file. The methods on this object don’t exist, and so are rescued by the <tt>method_missing</tt> defined further down in <tt>configuration.rb</tt>:</p>
|
752
|
+
<div class="code_container">
|
753
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
754
|
+
def method_missing(name, *args, &blk)
|
755
|
+
if name.to_s =~ /=$/
|
756
|
+
@@options[$`.to_sym] = args.first
|
757
|
+
elsif @@options.key?(name)
|
758
|
+
@@options[name]
|
759
|
+
else
|
760
|
+
super
|
761
|
+
end
|
762
|
+
end
|
763
|
+
</pre>
|
764
|
+
</div>
|
765
|
+
<p>So therefore when an option is referred to it simply stores the value as the key if it’s used in a setter context, or retrieves it if used in a getter context. Nothing fancy going on there.</p>
|
766
|
+
<h4 id="back-to-activesupport-lib-active_support-i18n_railtie-rb">2.37 Back to <tt>activesupport/lib/active_support/i18n_railtie.rb</tt></h4>
|
767
|
+
<p>After the configuration method the <tt>reloader</tt> method is defined, and then the first of of Railties’ initializers is defined: <tt>i18n.callbacks</tt>.</p>
|
768
|
+
<div class="code_container">
|
769
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
770
|
+
initializer "i18n.callbacks" do
|
771
|
+
ActionDispatch::Reloader.to_prepare do
|
772
|
+
I18n::Railtie.reloader.execute_if_updated
|
773
|
+
end
|
774
|
+
end
|
775
|
+
</pre>
|
776
|
+
</div>
|
777
|
+
<p>The <tt>initializer</tt> method (from the <tt>Rails::Initializable</tt> module) here doesn’t run the block, but rather stores it to be run later on:</p>
|
778
|
+
<div class="code_container">
|
779
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
780
|
+
def initializer(name, opts = {}, &blk)
|
781
|
+
raise ArgumentError, "A block must be passed when defining an initializer" unless blk
|
782
|
+
opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
|
783
|
+
initializers << Initializer.new(name, nil, opts, &blk)
|
784
|
+
end
|
785
|
+
</pre>
|
786
|
+
</div>
|
787
|
+
<p>An initializer can be configured to run before or after another initializer, which we’ll see a couple of times throughout this initialization process. Anything that inherits from <tt>Rails::Railtie</tt> may also make use of the <tt>initializer</tt> method, something which is covered in the <a href="[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer">Configuration guide</a>].</p>
|
788
|
+
<p>The <tt>Initializer</tt> class here is defined within the <tt>Rails::Initializable</tt> module and its <tt>initialize</tt> method is defined to just set up a couple of variables:</p>
|
789
|
+
<div class="code_container">
|
790
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
791
|
+
def initialize(name, context, options, &block)
|
792
|
+
@name, @context, @options, @block = name, context, options, block
|
793
|
+
end
|
794
|
+
</pre>
|
795
|
+
</div>
|
796
|
+
<p>Once this <tt>initialize</tt> method is finished, the object is added to the object the <tt>initializers</tt> method returns:</p>
|
797
|
+
<div class="code_container">
|
798
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
799
|
+
def initializers
|
800
|
+
@initializers ||= self.class.initializers_for(self)
|
801
|
+
end
|
802
|
+
</pre>
|
803
|
+
</div>
|
804
|
+
<p>If <tt>@initializers</tt> isn’t set (which it won’t be at this point), the <tt>intializers_for</tt> method will be called for this class.</p>
|
805
|
+
<div class="code_container">
|
806
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
807
|
+
def initializers_for(binding)
|
808
|
+
Collection.new(initializers_chain.map { |i| i.bind(binding) })
|
809
|
+
end
|
810
|
+
</pre>
|
811
|
+
</div>
|
812
|
+
<p>The <tt>Collection</tt> class in <tt>railties/lib/rails/initializable.rb</tt> inherits from <tt>Array</tt> and includes the <tt>TSort</tt> module which is used to sort out the order of the initializers based on the order they are placed in.</p>
|
813
|
+
<p>The <tt>initializers_chain</tt> method referenced in the <tt>initializers_for</tt> method is defined like this:</p>
|
814
|
+
<div class="code_container">
|
815
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
816
|
+
def initializers_chain
|
817
|
+
initializers = Collection.new
|
818
|
+
ancestors.reverse_each do | klass |
|
819
|
+
next unless klass.respond_to?(:initializers)
|
820
|
+
initializers = initializers + klass.initializers
|
821
|
+
end
|
822
|
+
initializers
|
823
|
+
end
|
824
|
+
</pre>
|
825
|
+
</div>
|
826
|
+
<p>This method collects the initializers from the ancestors of this class and adds them to a new <tt>Collection</tt> object using the <tt>+</tt> method which is defined like this for the <tt>Collection</tt> class:</p>
|
827
|
+
<div class="code_container">
|
828
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
829
|
+
def +(other)
|
830
|
+
Collection.new(to_a + other.to_a)
|
831
|
+
end
|
832
|
+
</pre>
|
833
|
+
</div>
|
834
|
+
<p>So this <tt><tt></tt> method is overridden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#</tt></tt> method combines these two collections, returning a “super” <tt>Collection</tt> object. In this case, the only initializer that’s going to be in this new <tt>Collection</tt> object is the <tt>i18n.callbacks</tt> initializer.</p>
|
835
|
+
<p>The next method to be called after this <tt>initializer</tt> method is the <tt>after_initialize</tt> method on the <tt>config</tt> object, which is defined like this:</p>
|
836
|
+
<div class="code_container">
|
837
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
838
|
+
def after_initialize(&block)
|
839
|
+
ActiveSupport.on_load(:after_initialize, :yield => true, &block)
|
840
|
+
end
|
841
|
+
</pre>
|
842
|
+
</div>
|
843
|
+
<p>The <tt>on_load</tt> method here is provided by the <tt>active_support/lazy_load_hooks</tt> file which was required earlier and is defined like this:</p>
|
844
|
+
<div class="code_container">
|
845
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
846
|
+
def self.on_load(name, options = {}, &block)
|
847
|
+
if base = @loaded[name]
|
848
|
+
execute_hook(base, options, block)
|
849
|
+
else
|
850
|
+
@load_hooks[name] << [block, options]
|
851
|
+
end
|
852
|
+
end
|
853
|
+
</pre>
|
854
|
+
</div>
|
855
|
+
<p>The <tt>@loaded</tt> variable here is a hash containing elements representing the different components of Rails that have been loaded at this stage. Currently, this hash is empty. So the <tt>else</tt> is executed here, using the <tt>@load_hooks</tt> variable defined in <tt>active_support/lazy_load_hooks</tt>:</p>
|
856
|
+
<div class="code_container">
|
857
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
858
|
+
@load_hooks = Hash.new {|h,k| h[k] = [] }
|
859
|
+
</pre>
|
860
|
+
</div>
|
861
|
+
<p>This defines a new hash which has keys that default to empty arrays. This saves Rails from having to do something like this instead:</p>
|
862
|
+
<div class="code_container">
|
863
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
864
|
+
@load_hooks[name] = []
|
865
|
+
@load_hooks[name] << [block, options]
|
866
|
+
</pre>
|
867
|
+
</div>
|
868
|
+
<p>The value added to this array here consists of the block and options passed to <tt>after_initialize</tt>.</p>
|
869
|
+
<p>We’ll see these <tt>@load_hooks</tt> used later on in the initialization process.</p>
|
870
|
+
<p>This rest of <tt>i18n_railtie.rb</tt> defines the protected class methods <tt>include_fallback_modules</tt>, <tt>init_fallbacks</tt> and <tt>validate_fallbacks</tt>.</p>
|
871
|
+
<h4 id="back-to-activesupport-lib-active_support-railtie-rb">2.38 Back to <tt>activesupport/lib/active_support/railtie.rb</tt></h4>
|
872
|
+
<p>This file defines the <tt>ActiveSupport::Railtie</tt> constant which like the <tt>I18n::Railtie</tt> constant just defined, inherits from <tt>Rails::Railtie</tt> meaning the <tt>inherited</tt> method would be called again here, including <tt>Rails::Configurable</tt> into this class. This class makes use of <tt>Rails::Railtie</tt>’s <tt>config</tt> method again, setting up the configuration options for Active Support.</p>
|
873
|
+
<p>Then this Railtie sets up three more initializers:</p>
|
874
|
+
<ul>
|
875
|
+
<li><tt>active_support.initialize_whiny_nils</tt></li>
|
876
|
+
<li><tt>active_support.deprecation_behavior</tt></li>
|
877
|
+
<li><tt>active_support.initialize_time_zone</tt></li>
|
878
|
+
</ul>
|
879
|
+
<p>We will cover what each of these initializers do when they run.</p>
|
880
|
+
<p>Once the <tt>active_support/railtie</tt> file has finished loading the next file required from <tt>railties/lib/rails.rb</tt> is the <tt>action_dispatch/railtie</tt>.</p>
|
881
|
+
<h4 id="activesupport-lib-action_dispatch-railtie-rb">2.39 <tt>activesupport/lib/action_dispatch/railtie.rb</tt></h4>
|
882
|
+
<p>This file defines the <tt>ActionDispatch::Railtie</tt> class, but not before requiring <tt>action_dispatch</tt>.</p>
|
883
|
+
<h4 id="activesupport-lib-action_dispatch-rb">2.40 <tt>activesupport/lib/action_dispatch.rb</tt></h4>
|
884
|
+
<p>This file attempts to locate the <tt>active_support</tt> and <tt>active_model</tt> libraries by looking a couple of directories back from the current file and then adds the <tt>active_support</tt> and <tt>active_model</tt> <tt>lib</tt> directories to the load path, but only if they aren’t already, which they are.</p>
|
885
|
+
<div class="code_container">
|
886
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
887
|
+
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
|
888
|
+
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
|
889
|
+
|
890
|
+
activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
|
891
|
+
$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
|
892
|
+
</pre>
|
893
|
+
</div>
|
894
|
+
<p>In effect, these lines only define the <tt>activesupport_path</tt> and <tt>activemodel_path</tt> variables and nothing more.</p>
|
895
|
+
<p>The next two requires in this file are already done, so they are not run:</p>
|
896
|
+
<div class="code_container">
|
897
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
898
|
+
require 'active_support'
|
899
|
+
require 'active_support/dependencies/autoload'
|
900
|
+
</pre>
|
901
|
+
</div>
|
902
|
+
<p>The following require is to <tt>action_pack</tt> (<tt>activesupport/lib/action_pack.rb</tt>) which has a 22-line copyright notice at the top of it and ends in a simple require to <tt>action_pack/version</tt>. This file, like other <tt>version.rb</tt> files before it, defines the <tt>ActionPack::VERSION</tt> constant:</p>
|
903
|
+
<div class="code_container">
|
904
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
905
|
+
module ActionPack
|
906
|
+
module VERSION #:nodoc:
|
907
|
+
MAJOR = 3
|
908
|
+
MINOR = 1
|
909
|
+
TINY = 0
|
910
|
+
PRE = "beta"
|
911
|
+
|
912
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
913
|
+
end
|
914
|
+
end
|
915
|
+
</pre>
|
916
|
+
</div>
|
917
|
+
<p>Once <tt>action_pack</tt> is finished, then <tt>active_model</tt> is required.</p>
|
918
|
+
<h4 id="activemodel-lib-active_model-rb">2.41 <tt>activemodel/lib/active_model.rb</tt></h4>
|
919
|
+
<p>This file makes a require to <tt>active_model/version</tt> which defines the version for Active Model:</p>
|
920
|
+
<div class="code_container">
|
921
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
922
|
+
module ActiveModel
|
923
|
+
module VERSION #:nodoc:
|
924
|
+
MAJOR = 3
|
925
|
+
MINOR = 1
|
926
|
+
TINY = 0
|
927
|
+
PRE = "beta"
|
928
|
+
|
929
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
930
|
+
end
|
931
|
+
end
|
932
|
+
</pre>
|
933
|
+
</div>
|
934
|
+
<p>Once the <tt>version.rb</tt> file is loaded, the <tt>ActiveModel</tt> module has its autoloaded constants defined as well as a sub-module called <tt>ActiveModel::Serializers</tt> which has autoloads of its own. When the <tt>ActiveModel</tt> module is closed the <tt>active_support/i18n</tt> file is required.</p>
|
935
|
+
<h4 id="activesupport-lib-active_support-i18n-rb">2.42 <tt>activesupport/lib/active_support/i18n.rb</tt></h4>
|
936
|
+
<p>This is where the <tt>i18n</tt> gem is required and first configured:</p>
|
937
|
+
<div class="code_container">
|
938
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
939
|
+
begin
|
940
|
+
require 'i18n'
|
941
|
+
require 'active_support/lazy_load_hooks'
|
942
|
+
rescue LoadError => e
|
943
|
+
$stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install"
|
944
|
+
raise e
|
945
|
+
end
|
946
|
+
|
947
|
+
I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
|
948
|
+
</pre>
|
949
|
+
</div>
|
950
|
+
<p>In effect, the <tt>I18n</tt> module first defined by <tt>i18n_railtie</tt> is extended by the <tt>i18n</tt> gem, rather than the other way around. This has no ill effect. They both work on the same way.</p>
|
951
|
+
<p>This is another spot where <tt>active_support/lazy_load_hooks</tt> is required, but it has already been required so it’s not loaded again.</p>
|
952
|
+
<p>If <tt>i18n</tt> cannot be loaded, the user is presented with an error which says that it cannot be loaded and recommends that it’s added to the <tt>Gemfile</tt>. However, in a normal Rails application this gem would be loaded.</p>
|
953
|
+
<p>Once it has finished loading, the <tt>I18n.load_path</tt> method is used to add the <tt>activesupport/lib/active_support/locale/en.yml</tt> file to I18n’s load path. When the translations are loaded in the initialization process, this is one of the files where they will be sourced from.</p>
|
954
|
+
<p>The loading of this file finishes the loading of <tt>active_model</tt> and so we go back to <tt>action_dispatch</tt>.</p>
|
955
|
+
<h4 id="back-to-activesupport-lib-action_dispatch-rb">2.43 Back to <tt>activesupport/lib/action_dispatch.rb</tt></h4>
|
956
|
+
<p>The remainder of this file requires the <tt>rack</tt> file from the Rack gem which defines the <tt>Rack</tt> module. After <tt>rack</tt>, there’s autoloads defined for the <tt>Rack</tt>, <tt>ActionDispatch</tt>, <tt>ActionDispatch::Http</tt>, <tt>ActionDispatch::Session</tt>. A new method called <tt>autoload_under</tt> is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here:</p>
|
957
|
+
<div class="code_container">
|
958
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
959
|
+
autoload_under 'testing' do
|
960
|
+
autoload :Assertions
|
961
|
+
...
|
962
|
+
</pre>
|
963
|
+
</div>
|
964
|
+
<p>The <tt>Assertions</tt> module is in the <tt>action_dispatch/testing</tt> folder rather than simply <tt>action_dispatch</tt>.</p>
|
965
|
+
<p>Finally, this file defines a top-level autoload, the <tt>Mime</tt> constant.</p>
|
966
|
+
<h4 id="back-to-activesupport-lib-action_dispatch-railtie-rb">2.44 Back to <tt>activesupport/lib/action_dispatch/railtie.rb</tt></h4>
|
967
|
+
<p>After <tt>action_dispatch</tt> is required in this file, the <tt>ActionDispatch::Railtie</tt> class is defined and is yet another class that inherits from <tt>Rails::Railtie</tt>. This class defines some initial configuration option defaults for <tt>config.action_dispatch</tt> before setting up a single initializer called <tt>action_dispatch.configure</tt>.</p>
|
968
|
+
<p>With <tt>action_dispatch/railtie</tt> now complete, we go back to <tt>railties/lib/rails.rb</tt>.</p>
|
969
|
+
<h4 id="back-to-railties-lib-rails-rb">2.45 Back to <tt>railties/lib/rails.rb</tt></h4>
|
970
|
+
<p>With the Active Support and Action Dispatch railties now both loaded, the rest of this file deals with setting up <span class="caps">UTF</span>-8 to be the default encoding for Rails and then finally setting up the <tt>Rails</tt> module. This module defines useful methods such as <tt>Rails.logger</tt>, <tt>Rails.application</tt>, <tt>Rails.env</tt>, and <tt>Rails.root</tt>.</p>
|
971
|
+
<h4 id="back-to-railties-lib-rails-all-rb">2.46 Back to <tt>railties/lib/rails/all.rb</tt></h4>
|
972
|
+
<p>Now that <tt>rails.rb</tt> is required, the remaining railties are loaded next, beginning with <tt>active_record/railtie</tt>.</p>
|
973
|
+
<h4 id="activerecord-lib-active_record-railtie-rb">2.47 <tt>activerecord/lib/active_record/railtie.rb</tt></h4>
|
974
|
+
<p>Before this file gets into the swing of defining the <tt>ActiveRecord::Railtie</tt> class, there are a couple of files that are required first. The first one of these is <tt>active_record</tt>.</p>
|
975
|
+
<h4 id="activerecord-lib-active_record-rb">2.48 <tt>activerecord/lib/active_record.rb</tt></h4>
|
976
|
+
<p>This file begins by detecting if the <tt>lib</tt> directories of <tt>active_support</tt> and <tt>active_model</tt> are not in the load path and if they aren’t then adds them. As we saw back in <tt>action_dispatch.rb</tt>, these directories are already there.</p>
|
977
|
+
<p>The first three requires have already been done by other files and so aren’t loaded here, but the 4th require, the one to <tt>arel</tt> will require the file provided by the Arel gem, which defines the <tt>Arel</tt> module.</p>
|
978
|
+
<div class="code_container">
|
979
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
980
|
+
require 'active_support'
|
981
|
+
require 'active_support/i18n'
|
982
|
+
require 'active_model'
|
983
|
+
require 'arel'
|
984
|
+
</pre>
|
985
|
+
</div>
|
986
|
+
<p>The 5th require in this file is one to <tt>active_record/version</tt> which defines the <tt>ActiveRecord::VERSION</tt> constant:</p>
|
987
|
+
<div class="code_container">
|
988
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
989
|
+
module ActiveRecord
|
990
|
+
module VERSION #:nodoc:
|
991
|
+
MAJOR = 3
|
992
|
+
MINOR = 1
|
993
|
+
TINY = 0
|
994
|
+
PRE = "beta"
|
995
|
+
|
996
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
997
|
+
end
|
998
|
+
end
|
999
|
+
</pre>
|
1000
|
+
</div>
|
1001
|
+
<p>Once these requires are finished, the base for the <tt>ActiveRecord</tt> module is defined along with its autoloads.</p>
|
1002
|
+
<p>Near the end of the file, we see this line:</p>
|
1003
|
+
<div class="code_container">
|
1004
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
1005
|
+
ActiveSupport.on_load(:active_record) do
|
1006
|
+
Arel::Table.engine = self
|
1007
|
+
end
|
1008
|
+
</pre>
|
1009
|
+
</div>
|
1010
|
+
<p>This will set the engine for <tt>Arel::Table</tt> to be <tt>ActiveRecord::Base</tt>.</p>
|
1011
|
+
<p>The file then finishes with this line:</p>
|
1012
|
+
<div class="code_container">
|
1013
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
1014
|
+
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
|
1015
|
+
</pre>
|
1016
|
+
</div>
|
1017
|
+
<p>This will add the translations from <tt>activerecord/lib/active_record/locale/en.yml</tt> to the load path for <tt>I18n</tt>, with this file being parsed when all the translations are loaded.</p>
|
1018
|
+
<h4 id="back-to-activerecord-lib-active_record-railtie-rb">2.49 Back to <tt>activerecord/lib/active_record/railtie.rb</tt></h4>
|
1019
|
+
<p>The next two <tt>require</tt>s in this file aren’t run because their files are already required, with <tt>rails</tt> being required by <tt>rails/all</tt> and <tt>active_model/railtie</tt> being required from <tt>action_dispatch</tt>.</p>
|
1020
|
+
<div class="code_container">
|
1021
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
1022
|
+
require "rails"
|
1023
|
+
require "active_model/railtie"
|
1024
|
+
</pre>
|
1025
|
+
</div>
|
1026
|
+
<p>The next <tt>require</tt> in this file is to <tt>action_controller/railtie</tt>.</p>
|
1027
|
+
<h4 id="actionpack-lib-action_controller-railtie-rb">2.50 <tt>actionpack/lib/action_controller/railtie.rb</tt></h4>
|
1028
|
+
<p>This file begins with a couple more requires to files that have already been loaded:</p>
|
1029
|
+
<div class="code_container">
|
1030
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
1031
|
+
require "rails"
|
1032
|
+
require "action_controller"
|
1033
|
+
require "action_dispatch/railtie"
|
1034
|
+
</pre>
|
1035
|
+
</div>
|
1036
|
+
<p>However the require after these is to a file that hasn’t yet been loaded, <tt>action_view/railtie</tt>, which begins by requiring <tt>action_view</tt>.</p>
|
1037
|
+
<h4 id="actionpack-lib-action_view-rb">2.51 <tt>actionpack/lib/action_view.rb</tt></h4>
|
1038
|
+
<tt>action_view.rb</tt>
|
1039
|
+
|
1040
|
+
<h3>Feedback</h3>
|
1041
|
+
<p>
|
1042
|
+
You're encouraged to help improve the quality of this guide.
|
1043
|
+
</p>
|
1044
|
+
<p>
|
1045
|
+
If you see any typos or factual errors you are confident to
|
1046
|
+
patch, please clone <a href="https://github.com/lifo/docrails">docrails</a>
|
1047
|
+
and push the change yourself. That branch of Rails has public write access.
|
1048
|
+
Commits are still reviewed, but that happens after you've submitted your
|
1049
|
+
contribution. <a href="https://github.com/lifo/docrails">docrails</a> is
|
1050
|
+
cross-merged with master periodically.
|
1051
|
+
</p>
|
1052
|
+
<p>
|
1053
|
+
You may also find incomplete content, or stuff that is not up to date.
|
1054
|
+
Please do add any missing documentation for master. Check the
|
1055
|
+
<a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a>
|
1056
|
+
for style and conventions.
|
1057
|
+
</p>
|
1058
|
+
<p>
|
1059
|
+
If for whatever reason you spot something to fix but cannot patch it yourself, please
|
1060
|
+
<a href="https://github.com/rails/rails/issues">open an issue</a>.
|
1061
|
+
</p>
|
1062
|
+
<p>And last but not least, any kind of discussion regarding Ruby on Rails
|
1063
|
+
documentation is very welcome in the <a href="http://groups.google.com/group/rubyonrails-docs">rubyonrails-docs mailing list</a>.
|
1064
|
+
</p>
|
1065
|
+
</div>
|
1066
|
+
</div>
|
1067
|
+
</div>
|
1068
|
+
|
1069
|
+
<hr class="hide" />
|
1070
|
+
<div id="footer">
|
1071
|
+
<div class="wrapper">
|
1072
|
+
<p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
|
1073
|
+
<p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
|
1074
|
+
</div>
|
1075
|
+
</div>
|
1076
|
+
|
1077
|
+
<script type="text/javascript" src="javascripts/guides.js"></script>
|
1078
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
|
1079
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
|
1080
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
|
1081
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
|
1082
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
|
1083
|
+
<script type="text/javascript">
|
1084
|
+
SyntaxHighlighter.all()
|
1085
|
+
</script>
|
1086
|
+
</body>
|
1087
|
+
</html>
|