rails 4.2.11 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +14 -10
  3. metadata +37 -238
  4. data/guides/CHANGELOG.md +0 -98
  5. data/guides/Rakefile +0 -92
  6. data/guides/assets/images/akshaysurve.jpg +0 -0
  7. data/guides/assets/images/belongs_to.png +0 -0
  8. data/guides/assets/images/book_icon.gif +0 -0
  9. data/guides/assets/images/bullet.gif +0 -0
  10. data/guides/assets/images/chapters_icon.gif +0 -0
  11. data/guides/assets/images/check_bullet.gif +0 -0
  12. data/guides/assets/images/credits_pic_blank.gif +0 -0
  13. data/guides/assets/images/csrf.png +0 -0
  14. data/guides/assets/images/edge_badge.png +0 -0
  15. data/guides/assets/images/favicon.ico +0 -0
  16. data/guides/assets/images/feature_tile.gif +0 -0
  17. data/guides/assets/images/footer_tile.gif +0 -0
  18. data/guides/assets/images/fxn.png +0 -0
  19. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  20. data/guides/assets/images/getting_started/challenge.png +0 -0
  21. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  22. data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  23. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  24. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  25. data/guides/assets/images/getting_started/new_article.png +0 -0
  26. data/guides/assets/images/getting_started/rails_welcome.png +0 -0
  27. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  28. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  29. data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
  30. data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
  31. data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
  32. data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
  33. data/guides/assets/images/grey_bullet.gif +0 -0
  34. data/guides/assets/images/habtm.png +0 -0
  35. data/guides/assets/images/has_many.png +0 -0
  36. data/guides/assets/images/has_many_through.png +0 -0
  37. data/guides/assets/images/has_one.png +0 -0
  38. data/guides/assets/images/has_one_through.png +0 -0
  39. data/guides/assets/images/header_backdrop.png +0 -0
  40. data/guides/assets/images/header_tile.gif +0 -0
  41. data/guides/assets/images/i18n/demo_html_safe.png +0 -0
  42. data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
  43. data/guides/assets/images/i18n/demo_translated_en.png +0 -0
  44. data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
  45. data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
  46. data/guides/assets/images/i18n/demo_untranslated.png +0 -0
  47. data/guides/assets/images/icons/README +0 -5
  48. data/guides/assets/images/icons/callouts/1.png +0 -0
  49. data/guides/assets/images/icons/callouts/10.png +0 -0
  50. data/guides/assets/images/icons/callouts/11.png +0 -0
  51. data/guides/assets/images/icons/callouts/12.png +0 -0
  52. data/guides/assets/images/icons/callouts/13.png +0 -0
  53. data/guides/assets/images/icons/callouts/14.png +0 -0
  54. data/guides/assets/images/icons/callouts/15.png +0 -0
  55. data/guides/assets/images/icons/callouts/2.png +0 -0
  56. data/guides/assets/images/icons/callouts/3.png +0 -0
  57. data/guides/assets/images/icons/callouts/4.png +0 -0
  58. data/guides/assets/images/icons/callouts/5.png +0 -0
  59. data/guides/assets/images/icons/callouts/6.png +0 -0
  60. data/guides/assets/images/icons/callouts/7.png +0 -0
  61. data/guides/assets/images/icons/callouts/8.png +0 -0
  62. data/guides/assets/images/icons/callouts/9.png +0 -0
  63. data/guides/assets/images/icons/caution.png +0 -0
  64. data/guides/assets/images/icons/example.png +0 -0
  65. data/guides/assets/images/icons/home.png +0 -0
  66. data/guides/assets/images/icons/important.png +0 -0
  67. data/guides/assets/images/icons/next.png +0 -0
  68. data/guides/assets/images/icons/note.png +0 -0
  69. data/guides/assets/images/icons/prev.png +0 -0
  70. data/guides/assets/images/icons/tip.png +0 -0
  71. data/guides/assets/images/icons/up.png +0 -0
  72. data/guides/assets/images/icons/warning.png +0 -0
  73. data/guides/assets/images/nav_arrow.gif +0 -0
  74. data/guides/assets/images/oscardelben.jpg +0 -0
  75. data/guides/assets/images/polymorphic.png +0 -0
  76. data/guides/assets/images/radar.png +0 -0
  77. data/guides/assets/images/rails4_features.png +0 -0
  78. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  79. data/guides/assets/images/rails_guides_logo.gif +0 -0
  80. data/guides/assets/images/rails_logo_remix.gif +0 -0
  81. data/guides/assets/images/session_fixation.png +0 -0
  82. data/guides/assets/images/tab_grey.gif +0 -0
  83. data/guides/assets/images/tab_info.gif +0 -0
  84. data/guides/assets/images/tab_note.gif +0 -0
  85. data/guides/assets/images/tab_red.gif +0 -0
  86. data/guides/assets/images/tab_yellow.gif +0 -0
  87. data/guides/assets/images/tab_yellow.png +0 -0
  88. data/guides/assets/images/vijaydev.jpg +0 -0
  89. data/guides/assets/javascripts/guides.js +0 -59
  90. data/guides/assets/javascripts/jquery.min.js +0 -4
  91. data/guides/assets/javascripts/responsive-tables.js +0 -43
  92. data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +0 -59
  93. data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +0 -75
  94. data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +0 -59
  95. data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +0 -65
  96. data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +0 -100
  97. data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +0 -97
  98. data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +0 -91
  99. data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +0 -55
  100. data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +0 -41
  101. data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +0 -52
  102. data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +0 -67
  103. data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +0 -52
  104. data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +0 -57
  105. data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +0 -58
  106. data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +0 -72
  107. data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +0 -88
  108. data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +0 -33
  109. data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +0 -74
  110. data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +0 -64
  111. data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +0 -55
  112. data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +0 -94
  113. data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +0 -51
  114. data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +0 -66
  115. data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +0 -56
  116. data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +0 -69
  117. data/guides/assets/javascripts/syntaxhighlighter/shCore.js +0 -17
  118. data/guides/assets/stylesheets/fixes.css +0 -16
  119. data/guides/assets/stylesheets/kindle.css +0 -11
  120. data/guides/assets/stylesheets/main.css +0 -713
  121. data/guides/assets/stylesheets/print.css +0 -52
  122. data/guides/assets/stylesheets/reset.css +0 -43
  123. data/guides/assets/stylesheets/responsive-tables.css +0 -50
  124. data/guides/assets/stylesheets/style.css +0 -13
  125. data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +0 -226
  126. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +0 -328
  127. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +0 -331
  128. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +0 -339
  129. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +0 -324
  130. data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +0 -328
  131. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +0 -324
  132. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +0 -324
  133. data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +0 -324
  134. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +0 -117
  135. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +0 -120
  136. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +0 -128
  137. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +0 -113
  138. data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +0 -117
  139. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +0 -113
  140. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +0 -113
  141. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +0 -113
  142. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +0 -116
  143. data/guides/bug_report_templates/action_controller_gem.rb +0 -47
  144. data/guides/bug_report_templates/action_controller_master.rb +0 -54
  145. data/guides/bug_report_templates/active_record_gem.rb +0 -40
  146. data/guides/bug_report_templates/active_record_master.rb +0 -49
  147. data/guides/bug_report_templates/generic_gem.rb +0 -15
  148. data/guides/bug_report_templates/generic_master.rb +0 -26
  149. data/guides/rails_guides.rb +0 -63
  150. data/guides/rails_guides/generator.rb +0 -248
  151. data/guides/rails_guides/helpers.rb +0 -53
  152. data/guides/rails_guides/indexer.rb +0 -68
  153. data/guides/rails_guides/kindle.rb +0 -119
  154. data/guides/rails_guides/levenshtein.rb +0 -37
  155. data/guides/rails_guides/markdown.rb +0 -167
  156. data/guides/rails_guides/markdown/renderer.rb +0 -82
  157. data/guides/source/2_2_release_notes.md +0 -435
  158. data/guides/source/2_3_release_notes.md +0 -621
  159. data/guides/source/3_0_release_notes.md +0 -611
  160. data/guides/source/3_1_release_notes.md +0 -559
  161. data/guides/source/3_2_release_notes.md +0 -568
  162. data/guides/source/4_0_release_notes.md +0 -279
  163. data/guides/source/4_1_release_notes.md +0 -730
  164. data/guides/source/4_2_release_notes.md +0 -877
  165. data/guides/source/_license.html.erb +0 -2
  166. data/guides/source/_welcome.html.erb +0 -23
  167. data/guides/source/action_controller_overview.md +0 -1192
  168. data/guides/source/action_mailer_basics.md +0 -757
  169. data/guides/source/action_view_overview.md +0 -1561
  170. data/guides/source/active_job_basics.md +0 -339
  171. data/guides/source/active_model_basics.md +0 -554
  172. data/guides/source/active_record_basics.md +0 -374
  173. data/guides/source/active_record_callbacks.md +0 -413
  174. data/guides/source/active_record_migrations.md +0 -1018
  175. data/guides/source/active_record_postgresql.md +0 -433
  176. data/guides/source/active_record_querying.md +0 -1781
  177. data/guides/source/active_record_validations.md +0 -1179
  178. data/guides/source/active_support_core_extensions.md +0 -3856
  179. data/guides/source/active_support_instrumentation.md +0 -488
  180. data/guides/source/api_documentation_guidelines.md +0 -361
  181. data/guides/source/asset_pipeline.md +0 -1304
  182. data/guides/source/association_basics.md +0 -2245
  183. data/guides/source/autoloading_and_reloading_constants.md +0 -1311
  184. data/guides/source/caching_with_rails.md +0 -379
  185. data/guides/source/command_line.md +0 -625
  186. data/guides/source/configuring.md +0 -1070
  187. data/guides/source/contributing_to_ruby_on_rails.md +0 -628
  188. data/guides/source/credits.html.erb +0 -80
  189. data/guides/source/debugging_rails_applications.md +0 -861
  190. data/guides/source/development_dependencies_install.md +0 -289
  191. data/guides/source/documents.yaml +0 -205
  192. data/guides/source/engines.md +0 -1412
  193. data/guides/source/form_helpers.md +0 -1024
  194. data/guides/source/generators.md +0 -676
  195. data/guides/source/getting_started.md +0 -2086
  196. data/guides/source/i18n.md +0 -1087
  197. data/guides/source/index.html.erb +0 -28
  198. data/guides/source/initialization.md +0 -704
  199. data/guides/source/kindle/copyright.html.erb +0 -1
  200. data/guides/source/kindle/layout.html.erb +0 -27
  201. data/guides/source/kindle/rails_guides.opf.erb +0 -52
  202. data/guides/source/kindle/toc.html.erb +0 -24
  203. data/guides/source/kindle/toc.ncx.erb +0 -64
  204. data/guides/source/kindle/welcome.html.erb +0 -5
  205. data/guides/source/layout.html.erb +0 -140
  206. data/guides/source/layouts_and_rendering.md +0 -1226
  207. data/guides/source/maintenance_policy.md +0 -78
  208. data/guides/source/nested_model_forms.md +0 -228
  209. data/guides/source/plugins.md +0 -444
  210. data/guides/source/rails_application_templates.md +0 -266
  211. data/guides/source/rails_on_rack.md +0 -335
  212. data/guides/source/routing.md +0 -1155
  213. data/guides/source/ruby_on_rails_guides_guidelines.md +0 -127
  214. data/guides/source/security.md +0 -1024
  215. data/guides/source/testing.md +0 -1132
  216. data/guides/source/upgrading_ruby_on_rails.md +0 -1186
  217. data/guides/source/working_with_javascript_in_rails.md +0 -407
  218. data/guides/w3c_validator.rb +0 -97
@@ -1,28 +0,0 @@
1
- <% content_for :page_title do %>
2
- Ruby on Rails Guides
3
- <% end %>
4
-
5
- <% content_for :header_section do %>
6
- <%= render 'welcome' %>
7
- <% end %>
8
-
9
- <% content_for :index_section do %>
10
- <div id="subCol">
11
- <dl>
12
- <dt></dt>
13
- <dd class="kindle">Rails Guides are also available for <%= link_to 'Kindle', @mobi %>.</dd>
14
- <dd class="work-in-progress">Guides marked with this icon are currently being worked on and will not be available in the Guides Index menu. While still useful, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections.</dd>
15
- </dl>
16
- </div>
17
- <% end %>
18
-
19
- <% documents_by_section.each do |section| %>
20
- <h3><%= section['name'] %></h3>
21
- <dl>
22
- <% section['documents'].each do |document| %>
23
- <%= guide(document['name'], document['url'], work_in_progress: document['work_in_progress']) do %>
24
- <p><%= document['description'] %></p>
25
- <% end %>
26
- <% end %>
27
- </dl>
28
- <% end %>
@@ -1,704 +0,0 @@
1
- The Rails Initialization Process
2
- ================================
3
-
4
- This guide explains the internals of the initialization process in Rails
5
- as of Rails 4. It is an extremely in-depth guide and recommended for advanced Rails developers.
6
-
7
- After reading this guide, you will know:
8
-
9
- * How to use `rails server`.
10
- * The timeline of Rails' initialization sequence.
11
- * Where different files are required by the boot sequence.
12
- * How the Rails::Server interface is defined and used.
13
-
14
- --------------------------------------------------------------------------------
15
-
16
- This guide goes through every method call that is
17
- required to boot up the Ruby on Rails stack for a default Rails 4
18
- application, explaining each part in detail along the way. For this
19
- guide, we will be focusing on what happens when you execute `rails server`
20
- to boot your app.
21
-
22
- NOTE: Paths in this guide are relative to Rails or a Rails application unless otherwise specified.
23
-
24
- TIP: If you want to follow along while browsing the Rails [source
25
- code](https://github.com/rails/rails), we recommend that you use the `t`
26
- key binding to open the file finder inside GitHub and find files
27
- quickly.
28
-
29
- Launch!
30
- -------
31
-
32
- Let's start to boot and initialize the app. A Rails application is usually
33
- started by running `rails console` or `rails server`.
34
-
35
- ### `railties/bin/rails`
36
-
37
- The `rails` in the command `rails server` is a ruby executable in your load
38
- path. This executable contains the following lines:
39
-
40
- ```ruby
41
- version = ">= 0"
42
- load Gem.bin_path('railties', 'rails', version)
43
- ```
44
-
45
- If you try out this command in a Rails console, you would see that this loads
46
- `railties/bin/rails`. A part of the file `railties/bin/rails.rb` has the
47
- following code:
48
-
49
- ```ruby
50
- require "rails/cli"
51
- ```
52
-
53
- The file `railties/lib/rails/cli` in turn calls
54
- `Rails::AppRailsLoader.exec_app_rails`.
55
-
56
- ### `railties/lib/rails/app_rails_loader.rb`
57
-
58
- The primary goal of the function `exec_app_rails` is to execute your app's
59
- `bin/rails`. If the current directory does not have a `bin/rails`, it will
60
- navigate upwards until it finds a `bin/rails` executable. Thus one can invoke a
61
- `rails` command from anywhere inside a rails application.
62
-
63
- For `rails server` the equivalent of the following command is executed:
64
-
65
- ```bash
66
- $ exec ruby bin/rails server
67
- ```
68
-
69
- ### `bin/rails`
70
-
71
- This file is as follows:
72
-
73
- ```ruby
74
- #!/usr/bin/env ruby
75
- APP_PATH = File.expand_path('../../config/application', __FILE__)
76
- require_relative '../config/boot'
77
- require 'rails/commands'
78
- ```
79
-
80
- The `APP_PATH` constant will be used later in `rails/commands`. The `config/boot` file referenced here is the `config/boot.rb` file in our application which is responsible for loading Bundler and setting it up.
81
-
82
- ### `config/boot.rb`
83
-
84
- `config/boot.rb` contains:
85
-
86
- ```ruby
87
- # Set up gems listed in the Gemfile.
88
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
89
-
90
- require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
91
- ```
92
-
93
- In a standard Rails application, there's a `Gemfile` which declares all
94
- dependencies of the application. `config/boot.rb` sets
95
- `ENV['BUNDLE_GEMFILE']` to the location of this file. If the Gemfile
96
- exists, then `bundler/setup` is required. The require is used by Bundler to
97
- configure the load path for your Gemfile's dependencies.
98
-
99
- A standard Rails application depends on several gems, specifically:
100
-
101
- * actionmailer
102
- * actionpack
103
- * actionview
104
- * activemodel
105
- * activerecord
106
- * activesupport
107
- * arel
108
- * builder
109
- * bundler
110
- * erubis
111
- * i18n
112
- * mail
113
- * mime-types
114
- * rack
115
- * rack-cache
116
- * rack-mount
117
- * rack-test
118
- * rails
119
- * railties
120
- * rake
121
- * sqlite3
122
- * thor
123
- * tzinfo
124
-
125
- ### `rails/commands.rb`
126
-
127
- Once `config/boot.rb` has finished, the next file that is required is
128
- `rails/commands`, which helps in expanding aliases. In the current case, the
129
- `ARGV` array simply contains `server` which will be passed over:
130
-
131
- ```ruby
132
- ARGV << '--help' if ARGV.empty?
133
-
134
- aliases = {
135
- "g" => "generate",
136
- "d" => "destroy",
137
- "c" => "console",
138
- "s" => "server",
139
- "db" => "dbconsole",
140
- "r" => "runner"
141
- }
142
-
143
- command = ARGV.shift
144
- command = aliases[command] || command
145
-
146
- require 'rails/commands/commands_tasks'
147
-
148
- Rails::CommandsTasks.new(ARGV).run_command!(command)
149
- ```
150
-
151
- TIP: As you can see, an empty ARGV list will make Rails show the help
152
- snippet.
153
-
154
- If we had used `s` rather than `server`, Rails would have used the `aliases`
155
- defined here to find the matching command.
156
-
157
- ### `rails/commands/command_tasks.rb`
158
-
159
- When one types an incorrect rails command, the `run_command` is responsible for
160
- throwing an error message. If the command is valid, a method of the same name
161
- is called.
162
-
163
- ```ruby
164
- COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole application runner new version help)
165
-
166
- def run_command!(command)
167
- command = parse_command(command)
168
- if COMMAND_WHITELIST.include?(command)
169
- send(command)
170
- else
171
- write_error_message(command)
172
- end
173
- end
174
- ```
175
-
176
- With the `server` command, Rails will further run the following code:
177
-
178
- ```ruby
179
- def set_application_directory!
180
- Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
181
- end
182
-
183
- def server
184
- set_application_directory!
185
- require_command!("server")
186
-
187
- Rails::Server.new.tap do |server|
188
- # We need to require application after the server sets environment,
189
- # otherwise the --environment option given to the server won't propagate.
190
- require APP_PATH
191
- Dir.chdir(Rails.application.root)
192
- server.start
193
- end
194
- end
195
-
196
- def require_command!(command)
197
- require "rails/commands/#{command}"
198
- end
199
- ```
200
-
201
- This file will change into the Rails root directory (a path two directories up
202
- from `APP_PATH` which points at `config/application.rb`), but only if the
203
- `config.ru` file isn't found. This then requires `rails/commands/server` which
204
- sets up the `Rails::Server` class.
205
-
206
- ```ruby
207
- require 'fileutils'
208
- require 'optparse'
209
- require 'action_dispatch'
210
- require 'rails'
211
-
212
- module Rails
213
- class Server < ::Rack::Server
214
- ```
215
-
216
- `fileutils` and `optparse` are standard Ruby libraries which provide helper functions for working with files and parsing options.
217
-
218
- ### `actionpack/lib/action_dispatch.rb`
219
-
220
- Action Dispatch is the routing component of the Rails framework.
221
- It adds functionality like routing, session, and common middlewares.
222
-
223
- ### `rails/commands/server.rb`
224
-
225
- The `Rails::Server` class is defined in this file by inheriting from `Rack::Server`. When `Rails::Server.new` is called, this calls the `initialize` method in `rails/commands/server.rb`:
226
-
227
- ```ruby
228
- def initialize(*)
229
- super
230
- set_environment
231
- end
232
- ```
233
-
234
- Firstly, `super` is called which calls the `initialize` method on `Rack::Server`.
235
-
236
- ### Rack: `lib/rack/server.rb`
237
-
238
- `Rack::Server` is responsible for providing a common server interface for all Rack-based applications, which Rails is now a part of.
239
-
240
- The `initialize` method in `Rack::Server` simply sets a couple of variables:
241
-
242
- ```ruby
243
- def initialize(options = nil)
244
- @options = options
245
- @app = options[:app] if options && options[:app]
246
- end
247
- ```
248
-
249
- In this case, `options` will be `nil` so nothing happens in this method.
250
-
251
- After `super` has finished in `Rack::Server`, we jump back to `rails/commands/server.rb`. At this point, `set_environment` is called within the context of the `Rails::Server` object and this method doesn't appear to do much at first glance:
252
-
253
- ```ruby
254
- def set_environment
255
- ENV["RAILS_ENV"] ||= options[:environment]
256
- end
257
- ```
258
-
259
- In fact, the `options` method here does quite a lot. This method is defined in `Rack::Server` like this:
260
-
261
- ```ruby
262
- def options
263
- @options ||= parse_options(ARGV)
264
- end
265
- ```
266
-
267
- Then `parse_options` is defined like this:
268
-
269
- ```ruby
270
- def parse_options(args)
271
- options = default_options
272
-
273
- # Don't evaluate CGI ISINDEX parameters.
274
- # http://www.meb.uni-bonn.de/docs/cgi/cl.html
275
- args.clear if ENV.include?("REQUEST_METHOD")
276
-
277
- options.merge! opt_parser.parse!(args)
278
- options[:config] = ::File.expand_path(options[:config])
279
- ENV["RACK_ENV"] = options[:environment]
280
- options
281
- end
282
- ```
283
-
284
- With the `default_options` set to this:
285
-
286
- ```ruby
287
- def default_options
288
- environment = ENV['RACK_ENV'] || 'development'
289
- default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
290
-
291
- {
292
- :environment => environment,
293
- :pid => nil,
294
- :Port => 9292,
295
- :Host => default_host,
296
- :AccessLog => [],
297
- :config => "config.ru"
298
- }
299
- end
300
- ```
301
-
302
- There is no `REQUEST_METHOD` key in `ENV` so we can skip over that line. The next line merges in the options from `opt_parser` which is defined plainly in `Rack::Server`:
303
-
304
- ```ruby
305
- def opt_parser
306
- Options.new
307
- end
308
- ```
309
-
310
- The class **is** defined in `Rack::Server`, but is overwritten in `Rails::Server` to take different arguments. Its `parse!` method begins like this:
311
-
312
- ```ruby
313
- def parse!(args)
314
- args, options = args.dup, {}
315
-
316
- opt_parser = OptionParser.new do |opts|
317
- opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
318
- opts.on("-p", "--port=port", Integer,
319
- "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
320
- ...
321
- ```
322
-
323
- This method will set up keys for the `options` which Rails will then be
324
- able to use to determine how its server should run. After `initialize`
325
- has finished, we jump back into `rails/server` where `APP_PATH` (which was
326
- set earlier) is required.
327
-
328
- ### `config/application`
329
-
330
- When `require APP_PATH` is executed, `config/application.rb` is loaded (recall
331
- that `APP_PATH` is defined in `bin/rails`). This file exists in your application
332
- and it's free for you to change based on your needs.
333
-
334
- ### `Rails::Server#start`
335
-
336
- After `config/application` is loaded, `server.start` is called. This method is
337
- defined like this:
338
-
339
- ```ruby
340
- def start
341
- print_boot_information
342
- trap(:INT) { exit }
343
- create_tmp_directories
344
- log_to_stdout if options[:log_stdout]
345
-
346
- super
347
- ...
348
- end
349
-
350
- private
351
-
352
- def print_boot_information
353
- ...
354
- puts "=> Run `rails server -h` for more startup options"
355
- ...
356
- puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
357
- end
358
-
359
- def create_tmp_directories
360
- %w(cache pids sessions sockets).each do |dir_to_make|
361
- FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
362
- end
363
- end
364
-
365
- def log_to_stdout
366
- wrapped_app # touch the app so the logger is set up
367
-
368
- console = ActiveSupport::Logger.new($stdout)
369
- console.formatter = Rails.logger.formatter
370
- console.level = Rails.logger.level
371
-
372
- Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
373
- end
374
- ```
375
-
376
- This is where the first output of the Rails initialization happens. This
377
- method creates a trap for `INT` signals, so if you `CTRL-C` the server,
378
- it will exit the process. As we can see from the code here, it will
379
- create the `tmp/cache`, `tmp/pids`, `tmp/sessions` and `tmp/sockets`
380
- directories. It then calls `wrapped_app` which is responsible for
381
- creating the Rack app, before creating and assigning an
382
- instance of `ActiveSupport::Logger`.
383
-
384
- The `super` method will call `Rack::Server.start` which begins its definition like this:
385
-
386
- ```ruby
387
- def start &blk
388
- if options[:warn]
389
- $-w = true
390
- end
391
-
392
- if includes = options[:include]
393
- $LOAD_PATH.unshift(*includes)
394
- end
395
-
396
- if library = options[:require]
397
- require library
398
- end
399
-
400
- if options[:debug]
401
- $DEBUG = true
402
- require 'pp'
403
- p options[:server]
404
- pp wrapped_app
405
- pp app
406
- end
407
-
408
- check_pid! if options[:pid]
409
-
410
- # Touch the wrapped app, so that the config.ru is loaded before
411
- # daemonization (i.e. before chdir, etc).
412
- wrapped_app
413
-
414
- daemonize_app if options[:daemonize]
415
-
416
- write_pid if options[:pid]
417
-
418
- trap(:INT) do
419
- if server.respond_to?(:shutdown)
420
- server.shutdown
421
- else
422
- exit
423
- end
424
- end
425
-
426
- server.run wrapped_app, options, &blk
427
- end
428
- ```
429
-
430
- The interesting part for a Rails app is the last line, `server.run`. Here we encounter the `wrapped_app` method again, which this time
431
- we're going to explore more (even though it was executed before, and
432
- thus memoized by now).
433
-
434
- ```ruby
435
- @wrapped_app ||= build_app app
436
- ```
437
-
438
- The `app` method here is defined like so:
439
-
440
- ```ruby
441
- def app
442
- @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
443
- end
444
- ...
445
- private
446
- def build_app_and_options_from_config
447
- if !::File.exist? options[:config]
448
- abort "configuration #{options[:config]} not found"
449
- end
450
-
451
- app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
452
- self.options.merge! options
453
- app
454
- end
455
-
456
- def build_app_from_string
457
- Rack::Builder.new_from_string(self.options[:builder])
458
- end
459
- ```
460
-
461
- The `options[:config]` value defaults to `config.ru` which contains this:
462
-
463
- ```ruby
464
- # This file is used by Rack-based servers to start the application.
465
-
466
- require ::File.expand_path('../config/environment', __FILE__)
467
- run <%= app_const %>
468
- ```
469
-
470
-
471
- The `Rack::Builder.parse_file` method here takes the content from this `config.ru` file and parses it using this code:
472
-
473
- ```ruby
474
- app = new_from_string cfgfile, config
475
-
476
- ...
477
-
478
- def self.new_from_string(builder_script, file="(rackup)")
479
- eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
480
- TOPLEVEL_BINDING, file, 0
481
- end
482
- ```
483
-
484
- The `initialize` method of `Rack::Builder` will take the block here and execute it within an instance of `Rack::Builder`. This is where the majority of the initialization process of Rails happens. The `require` line for `config/environment.rb` in `config.ru` is the first to run:
485
-
486
- ```ruby
487
- require ::File.expand_path('../config/environment', __FILE__)
488
- ```
489
-
490
- ### `config/environment.rb`
491
-
492
- This file is the common file required by `config.ru` (`rails server`) and Passenger. This is where these two ways to run the server meet; everything before this point has been Rack and Rails setup.
493
-
494
- This file begins with requiring `config/application.rb`:
495
-
496
- ```ruby
497
- require File.expand_path('../application', __FILE__)
498
- ```
499
-
500
- ### `config/application.rb`
501
-
502
- This file requires `config/boot.rb`:
503
-
504
- ```ruby
505
- require File.expand_path('../boot', __FILE__)
506
- ```
507
-
508
- But only if it hasn't been required before, which would be the case in `rails server`
509
- but **wouldn't** be the case with Passenger.
510
-
511
- Then the fun begins!
512
-
513
- Loading Rails
514
- -------------
515
-
516
- The next line in `config/application.rb` is:
517
-
518
- ```ruby
519
- require 'rails/all'
520
- ```
521
-
522
- ### `railties/lib/rails/all.rb`
523
-
524
- This file is responsible for requiring all the individual frameworks of Rails:
525
-
526
- ```ruby
527
- require "rails"
528
-
529
- %w(
530
- active_record
531
- action_controller
532
- action_view
533
- action_mailer
534
- rails/test_unit
535
- sprockets
536
- ).each do |framework|
537
- begin
538
- require "#{framework}/railtie"
539
- rescue LoadError
540
- end
541
- end
542
- ```
543
-
544
- This is where all the Rails frameworks are loaded and thus made
545
- available to the application. We won't go into detail of what happens
546
- inside each of those frameworks, but you're encouraged to try and
547
- explore them on your own.
548
-
549
- For now, just keep in mind that common functionality like Rails engines,
550
- I18n and Rails configuration are all being defined here.
551
-
552
- ### Back to `config/environment.rb`
553
-
554
- The rest of `config/application.rb` defines the configuration for the
555
- `Rails::Application` which will be used once the application is fully
556
- initialized. When `config/application.rb` has finished loading Rails and defined
557
- the application namespace, we go back to `config/environment.rb`,
558
- where the application is initialized. For example, if the application was called
559
- `Blog`, here we would find `Rails.application.initialize!`, which is
560
- defined in `rails/application.rb`.
561
-
562
- ### `railties/lib/rails/application.rb`
563
-
564
- The `initialize!` method looks like this:
565
-
566
- ```ruby
567
- def initialize!(group=:default) #:nodoc:
568
- raise "Application has been already initialized." if @initialized
569
- run_initializers(group, self)
570
- @initialized = true
571
- self
572
- end
573
- ```
574
-
575
- As you can see, you can only initialize an app once. The initializers are run through
576
- the `run_initializers` method which is defined in `railties/lib/rails/initializable.rb`:
577
-
578
- ```ruby
579
- def run_initializers(group=:default, *args)
580
- return if instance_variable_defined?(:@ran)
581
- initializers.tsort_each do |initializer|
582
- initializer.run(*args) if initializer.belongs_to?(group)
583
- end
584
- @ran = true
585
- end
586
- ```
587
-
588
- The `run_initializers` code itself is tricky. What Rails is doing here is
589
- traversing all the class ancestors looking for those that respond to an
590
- `initializers` method. It then sorts the ancestors by name, and runs them.
591
- For example, the `Engine` class will make all the engines available by
592
- providing an `initializers` method on them.
593
-
594
- The `Rails::Application` class, as defined in `railties/lib/rails/application.rb`
595
- defines `bootstrap`, `railtie`, and `finisher` initializers. The `bootstrap` initializers
596
- prepare the application (like initializing the logger) while the `finisher`
597
- initializers (like building the middleware stack) are run last. The `railtie`
598
- initializers are the initializers which have been defined on the `Rails::Application`
599
- itself and are run between the `bootstrap` and `finishers`.
600
-
601
- After this is done we go back to `Rack::Server`.
602
-
603
- ### Rack: lib/rack/server.rb
604
-
605
- Last time we left when the `app` method was being defined:
606
-
607
- ```ruby
608
- def app
609
- @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
610
- end
611
- ...
612
- private
613
- def build_app_and_options_from_config
614
- if !::File.exist? options[:config]
615
- abort "configuration #{options[:config]} not found"
616
- end
617
-
618
- app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
619
- self.options.merge! options
620
- app
621
- end
622
-
623
- def build_app_from_string
624
- Rack::Builder.new_from_string(self.options[:builder])
625
- end
626
- ```
627
-
628
- At this point `app` is the Rails app itself (a middleware), and what
629
- happens next is Rack will call all the provided middlewares:
630
-
631
- ```ruby
632
- def build_app(app)
633
- middleware[options[:environment]].reverse_each do |middleware|
634
- middleware = middleware.call(self) if middleware.respond_to?(:call)
635
- next unless middleware
636
- klass = middleware.shift
637
- app = klass.new(app, *middleware)
638
- end
639
- app
640
- end
641
- ```
642
-
643
- Remember, `build_app` was called (by `wrapped_app`) in the last line of `Server#start`.
644
- Here's how it looked like when we left:
645
-
646
- ```ruby
647
- server.run wrapped_app, options, &blk
648
- ```
649
-
650
- At this point, the implementation of `server.run` will depend on the
651
- server you're using. For example, if you were using Puma, here's what
652
- the `run` method would look like:
653
-
654
- ```ruby
655
- ...
656
- DEFAULT_OPTIONS = {
657
- :Host => '0.0.0.0',
658
- :Port => 8080,
659
- :Threads => '0:16',
660
- :Verbose => false
661
- }
662
-
663
- def self.run(app, options = {})
664
- options = DEFAULT_OPTIONS.merge(options)
665
-
666
- if options[:Verbose]
667
- app = Rack::CommonLogger.new(app, STDOUT)
668
- end
669
-
670
- if options[:environment]
671
- ENV['RACK_ENV'] = options[:environment].to_s
672
- end
673
-
674
- server = ::Puma::Server.new(app)
675
- min, max = options[:Threads].split(':', 2)
676
-
677
- puts "Puma #{::Puma::Const::PUMA_VERSION} starting..."
678
- puts "* Min threads: #{min}, max threads: #{max}"
679
- puts "* Environment: #{ENV['RACK_ENV']}"
680
- puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
681
-
682
- server.add_tcp_listener options[:Host], options[:Port]
683
- server.min_threads = min
684
- server.max_threads = max
685
- yield server if block_given?
686
-
687
- begin
688
- server.run.join
689
- rescue Interrupt
690
- puts "* Gracefully stopping, waiting for requests to finish"
691
- server.stop(true)
692
- puts "* Goodbye!"
693
- end
694
-
695
- end
696
- ```
697
-
698
- We won't dig into the server configuration itself, but this is
699
- the last piece of our journey in the Rails initialization process.
700
-
701
- This high level overview will help you understand when your code is
702
- executed and how, and overall become a better Rails developer. If you
703
- still want to know more, the Rails source code itself is probably the
704
- best place to go next.