rails 4.2.7.1 → 6.1.2.1

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 +54 -36
  3. metadata +87 -249
  4. data/guides/CHANGELOG.md +0 -78
  5. data/guides/Rakefile +0 -79
  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 -3857
  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 -1072
  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 -336
  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,1311 +0,0 @@
1
- Autoloading and Reloading Constants
2
- ===================================
3
-
4
- This guide documents how constant autoloading and reloading works.
5
-
6
- After reading this guide, you will know:
7
-
8
- * Key aspects of Ruby constants
9
- * What is `autoload_paths`
10
- * How constant autoloading works
11
- * What is `require_dependency`
12
- * How constant reloading works
13
- * Solutions to common autoloading gotchas
14
-
15
- --------------------------------------------------------------------------------
16
-
17
-
18
- Introduction
19
- ------------
20
-
21
- Ruby on Rails allows applications to be written as if their code was preloaded.
22
-
23
- In a normal Ruby program classes need to load their dependencies:
24
-
25
- ```ruby
26
- require 'application_controller'
27
- require 'post'
28
-
29
- class PostsController < ApplicationController
30
- def index
31
- @posts = Post.all
32
- end
33
- end
34
- ```
35
-
36
- Our Rubyist instinct quickly sees some redundancy in there: If classes were
37
- defined in files matching their name, couldn't their loading be automated
38
- somehow? We could save scanning the file for dependencies, which is brittle.
39
-
40
- Moreover, `Kernel#require` loads files once, but development is much more smooth
41
- if code gets refreshed when it changes without restarting the server. It would
42
- be nice to be able to use `Kernel#load` in development, and `Kernel#require` in
43
- production.
44
-
45
- Indeed, those features are provided by Ruby on Rails, where we just write
46
-
47
- ```ruby
48
- class PostsController < ApplicationController
49
- def index
50
- @posts = Post.all
51
- end
52
- end
53
- ```
54
-
55
- This guide documents how that works.
56
-
57
-
58
- Constants Refresher
59
- -------------------
60
-
61
- While constants are trivial in most programming languages, they are a rich
62
- topic in Ruby.
63
-
64
- It is beyond the scope of this guide to document Ruby constants, but we are
65
- nevertheless going to highlight a few key topics. Truly grasping the following
66
- sections is instrumental to understanding constant autoloading and reloading.
67
-
68
- ### Nesting
69
-
70
- Class and module definitions can be nested to create namespaces:
71
-
72
- ```ruby
73
- module XML
74
- class SAXParser
75
- # (1)
76
- end
77
- end
78
- ```
79
-
80
- The *nesting* at any given place is the collection of enclosing nested class and
81
- module objects outwards. The nesting at any given place can be inspected with
82
- `Module.nesting`. For example, in the previous example, the nesting at
83
- (1) is
84
-
85
- ```ruby
86
- [XML::SAXParser, XML]
87
- ```
88
-
89
- It is important to understand that the nesting is composed of class and module
90
- *objects*, it has nothing to do with the constants used to access them, and is
91
- also unrelated to their names.
92
-
93
- For instance, while this definition is similar to the previous one:
94
-
95
- ```ruby
96
- class XML::SAXParser
97
- # (2)
98
- end
99
- ```
100
-
101
- the nesting in (2) is different:
102
-
103
- ```ruby
104
- [XML::SAXParser]
105
- ```
106
-
107
- `XML` does not belong to it.
108
-
109
- We can see in this example that the name of a class or module that belongs to a
110
- certain nesting does not necessarily correlate with the namespaces at the spot.
111
-
112
- Even more, they are totally independent, take for instance
113
-
114
- ```ruby
115
- module X
116
- module Y
117
- end
118
- end
119
-
120
- module A
121
- module B
122
- end
123
- end
124
-
125
- module X::Y
126
- module A::B
127
- # (3)
128
- end
129
- end
130
- ```
131
-
132
- The nesting in (3) consists of two module objects:
133
-
134
- ```ruby
135
- [A::B, X::Y]
136
- ```
137
-
138
- So, it not only doesn't end in `A`, which does not even belong to the nesting,
139
- but it also contains `X::Y`, which is independent from `A::B`.
140
-
141
- The nesting is an internal stack maintained by the interpreter, and it gets
142
- modified according to these rules:
143
-
144
- * The class object following a `class` keyword gets pushed when its body is
145
- executed, and popped after it.
146
-
147
- * The module object following a `module` keyword gets pushed when its body is
148
- executed, and popped after it.
149
-
150
- * A singleton class opened with `class << object` gets pushed, and popped later.
151
-
152
- * When `instance_eval` is called using a string argument,
153
- the singleton class of the receiver is pushed to the nesting of the eval'ed
154
- code. When `class_eval` or `module_eval` is called using a string argument,
155
- the receiver is pushed to the nesting of the eval'ed code.
156
-
157
- * The nesting at the top-level of code interpreted by `Kernel#load` is empty
158
- unless the `load` call receives a true value as second argument, in which case
159
- a newly created anonymous module is pushed by Ruby.
160
-
161
- It is interesting to observe that blocks do not modify the stack. In particular
162
- the blocks that may be passed to `Class.new` and `Module.new` do not get the
163
- class or module being defined pushed to their nesting. That's one of the
164
- differences between defining classes and modules in one way or another.
165
-
166
- ### Class and Module Definitions are Constant Assignments
167
-
168
- Let's suppose the following snippet creates a class (rather than reopening it):
169
-
170
- ```ruby
171
- class C
172
- end
173
- ```
174
-
175
- Ruby creates a constant `C` in `Object` and stores in that constant a class
176
- object. The name of the class instance is "C", a string, named after the
177
- constant.
178
-
179
- That is,
180
-
181
- ```ruby
182
- class Project < ActiveRecord::Base
183
- end
184
- ```
185
-
186
- performs a constant assignment equivalent to
187
-
188
- ```ruby
189
- Project = Class.new(ActiveRecord::Base)
190
- ```
191
-
192
- including setting the name of the class as a side-effect:
193
-
194
- ```ruby
195
- Project.name # => "Project"
196
- ```
197
-
198
- Constant assignment has a special rule to make that happen: if the object
199
- being assigned is an anonymous class or module, Ruby sets the object's name to
200
- the name of the constant.
201
-
202
- INFO. From then on, what happens to the constant and the instance does not
203
- matter. For example, the constant could be deleted, the class object could be
204
- assigned to a different constant, be stored in no constant anymore, etc. Once
205
- the name is set, it doesn't change.
206
-
207
- Similarly, module creation using the `module` keyword as in
208
-
209
- ```ruby
210
- module Admin
211
- end
212
- ```
213
-
214
- performs a constant assignment equivalent to
215
-
216
- ```ruby
217
- Admin = Module.new
218
- ```
219
-
220
- including setting the name as a side-effect:
221
-
222
- ```ruby
223
- Admin.name # => "Admin"
224
- ```
225
-
226
- WARNING. The execution context of a block passed to `Class.new` or `Module.new`
227
- is not entirely equivalent to the one of the body of the definitions using the
228
- `class` and `module` keywords. But both idioms result in the same constant
229
- assignment.
230
-
231
- Thus, when one informally says "the `String` class", that really means: the
232
- class object stored in the constant called "String" in the class object stored
233
- in the `Object` constant. `String` is otherwise an ordinary Ruby constant and
234
- everything related to constants such as resolution algorithms applies to it.
235
-
236
- Likewise, in the controller
237
-
238
- ```ruby
239
- class PostsController < ApplicationController
240
- def index
241
- @posts = Post.all
242
- end
243
- end
244
- ```
245
-
246
- `Post` is not syntax for a class. Rather, `Post` is a regular Ruby constant. If
247
- all is good, the constant is evaluated to an object that responds to `all`.
248
-
249
- That is why we talk about *constant* autoloading, Rails has the ability to
250
- load constants on the fly.
251
-
252
- ### Constants are Stored in Modules
253
-
254
- Constants belong to modules in a very literal sense. Classes and modules have
255
- a constant table; think of it as a hash table.
256
-
257
- Let's analyze an example to really understand what that means. While common
258
- abuses of language like "the `String` class" are convenient, the exposition is
259
- going to be precise here for didactic purposes.
260
-
261
- Let's consider the following module definition:
262
-
263
- ```ruby
264
- module Colors
265
- RED = '0xff0000'
266
- end
267
- ```
268
-
269
- First, when the `module` keyword is processed, the interpreter creates a new
270
- entry in the constant table of the class object stored in the `Object` constant.
271
- Said entry associates the name "Colors" to a newly created module object.
272
- Furthermore, the interpreter sets the name of the new module object to be the
273
- string "Colors".
274
-
275
- Later, when the body of the module definition is interpreted, a new entry is
276
- created in the constant table of the module object stored in the `Colors`
277
- constant. That entry maps the name "RED" to the string "0xff0000".
278
-
279
- In particular, `Colors::RED` is totally unrelated to any other `RED` constant
280
- that may live in any other class or module object. If there were any, they
281
- would have separate entries in their respective constant tables.
282
-
283
- Pay special attention in the previous paragraphs to the distinction between
284
- class and module objects, constant names, and value objects associated to them
285
- in constant tables.
286
-
287
- ### Resolution Algorithms
288
-
289
- #### Resolution Algorithm for Relative Constants
290
-
291
- At any given place in the code, let's define *cref* to be the first element of
292
- the nesting if it is not empty, or `Object` otherwise.
293
-
294
- Without getting too much into the details, the resolution algorithm for relative
295
- constant references goes like this:
296
-
297
- 1. If the nesting is not empty the constant is looked up in its elements and in
298
- order. The ancestors of those elements are ignored.
299
-
300
- 2. If not found, then the algorithm walks up the ancestor chain of the cref.
301
-
302
- 3. If not found and the cref is a module, the constant is looked up in `Object`.
303
-
304
- 4. If not found, `const_missing` is invoked on the cref. The default
305
- implementation of `const_missing` raises `NameError`, but it can be overridden.
306
-
307
- Rails autoloading **does not emulate this algorithm**, but its starting point is
308
- the name of the constant to be autoloaded, and the cref. See more in [Relative
309
- References](#autoloading-algorithms-relative-references).
310
-
311
- #### Resolution Algorithm for Qualified Constants
312
-
313
- Qualified constants look like this:
314
-
315
- ```ruby
316
- Billing::Invoice
317
- ```
318
-
319
- `Billing::Invoice` is composed of two constants: `Billing` is relative and is
320
- resolved using the algorithm of the previous section.
321
-
322
- INFO. Leading colons would make the first segment absolute rather than
323
- relative: `::Billing::Invoice`. That would force `Billing` to be looked up
324
- only as a top-level constant.
325
-
326
- `Invoice` on the other hand is qualified by `Billing` and we are going to see
327
- its resolution next. Let's define *parent* to be that qualifying class or module
328
- object, that is, `Billing` in the example above. The algorithm for qualified
329
- constants goes like this:
330
-
331
- 1. The constant is looked up in the parent and its ancestors.
332
-
333
- 2. If the lookup fails, `const_missing` is invoked in the parent. The default
334
- implementation of `const_missing` raises `NameError`, but it can be overridden.
335
-
336
- As you see, this algorithm is simpler than the one for relative constants. In
337
- particular, the nesting plays no role here, and modules are not special-cased,
338
- if neither they nor their ancestors have the constants, `Object` is **not**
339
- checked.
340
-
341
- Rails autoloading **does not emulate this algorithm**, but its starting point is
342
- the name of the constant to be autoloaded, and the parent. See more in
343
- [Qualified References](#autoloading-algorithms-qualified-references).
344
-
345
-
346
- Vocabulary
347
- ----------
348
-
349
- ### Parent Namespaces
350
-
351
- Given a string with a constant path we define its *parent namespace* to be the
352
- string that results from removing its rightmost segment.
353
-
354
- For example, the parent namespace of the string "A::B::C" is the string "A::B",
355
- the parent namespace of "A::B" is "A", and the parent namespace of "A" is "".
356
-
357
- The interpretation of a parent namespace when thinking about classes and modules
358
- is tricky though. Let's consider a module M named "A::B":
359
-
360
- * The parent namespace, "A", may not reflect nesting at a given spot.
361
-
362
- * The constant `A` may no longer exist, some code could have removed it from
363
- `Object`.
364
-
365
- * If `A` exists, the class or module that was originally in `A` may not be there
366
- anymore. For example, if after a constant removal there was another constant
367
- assignment there would generally be a different object in there.
368
-
369
- * In such case, it could even happen that the reassigned `A` held a new class or
370
- module called also "A"!
371
-
372
- * In the previous scenarios M would no longer be reachable through `A::B` but
373
- the module object itself could still be alive somewhere and its name would
374
- still be "A::B".
375
-
376
- The idea of a parent namespace is at the core of the autoloading algorithms
377
- and helps explain and understand their motivation intuitively, but as you see
378
- that metaphor leaks easily. Given an edge case to reason about, take always into
379
- account that by "parent namespace" the guide means exactly that specific string
380
- derivation.
381
-
382
- ### Loading Mechanism
383
-
384
- Rails autoloads files with `Kernel#load` when `config.cache_classes` is false,
385
- the default in development mode, and with `Kernel#require` otherwise, the
386
- default in production mode.
387
-
388
- `Kernel#load` allows Rails to execute files more than once if [constant
389
- reloading](#constant-reloading) is enabled.
390
-
391
- This guide uses the word "load" freely to mean a given file is interpreted, but
392
- the actual mechanism can be `Kernel#load` or `Kernel#require` depending on that
393
- flag.
394
-
395
-
396
- Autoloading Availability
397
- ------------------------
398
-
399
- Rails is always able to autoload provided its environment is in place. For
400
- example the `runner` command autoloads:
401
-
402
- ```
403
- $ bin/rails runner 'p User.column_names'
404
- ["id", "email", "created_at", "updated_at"]
405
- ```
406
-
407
- The console autoloads, the test suite autoloads, and of course the application
408
- autoloads.
409
-
410
- By default, Rails eager loads the application files when it boots in production
411
- mode, so most of the autoloading going on in development does not happen. But
412
- autoloading may still be triggered during eager loading.
413
-
414
- For example, given
415
-
416
- ```ruby
417
- class BeachHouse < House
418
- end
419
- ```
420
-
421
- if `House` is still unknown when `app/models/beach_house.rb` is being eager
422
- loaded, Rails autoloads it.
423
-
424
-
425
- autoload_paths
426
- --------------
427
-
428
- As you probably know, when `require` gets a relative file name:
429
-
430
- ```ruby
431
- require 'erb'
432
- ```
433
-
434
- Ruby looks for the file in the directories listed in `$LOAD_PATH`. That is, Ruby
435
- iterates over all its directories and for each one of them checks whether they
436
- have a file called "erb.rb", or "erb.so", or "erb.o", or "erb.dll". If it finds
437
- any of them, the interpreter loads it and ends the search. Otherwise, it tries
438
- again in the next directory of the list. If the list gets exhausted, `LoadError`
439
- is raised.
440
-
441
- We are going to cover how constant autoloading works in more detail later, but
442
- the idea is that when a constant like `Post` is hit and missing, if there's a
443
- `post.rb` file for example in `app/models` Rails is going to find it, evaluate
444
- it, and have `Post` defined as a side-effect.
445
-
446
- Alright, Rails has a collection of directories similar to `$LOAD_PATH` in which
447
- to look up `post.rb`. That collection is called `autoload_paths` and by
448
- default it contains:
449
-
450
- * All subdirectories of `app` in the application and engines. For example,
451
- `app/controllers`. They do not need to be the default ones, any custom
452
- directories like `app/workers` belong automatically to `autoload_paths`.
453
-
454
- * Second level directories `app/{controllers,models}/concerns` in the
455
- application and engines.
456
-
457
- * The directory `test/mailers/previews`.
458
-
459
- Also, this collection is configurable via `config.autoload_paths`. For example,
460
- `lib` was in the list years ago, but no longer is. An application can opt-in
461
- by adding this to `config/application.rb`:
462
-
463
- ```ruby
464
- config.autoload_paths << "#{Rails.root}/lib"
465
- ```
466
- `config.autoload_paths` is accessible from environment-specific configuration files, but any changes made to it outside `config/application.rb` don't have an effect.
467
-
468
- The value of `autoload_paths` can be inspected. In a just generated application
469
- it is (edited):
470
-
471
- ```
472
- $ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'
473
- .../app/assets
474
- .../app/controllers
475
- .../app/helpers
476
- .../app/mailers
477
- .../app/models
478
- .../app/controllers/concerns
479
- .../app/models/concerns
480
- .../test/mailers/previews
481
- ```
482
-
483
- INFO. `autoload_paths` is computed and cached during the initialization process.
484
- The application needs to be restarted to reflect any changes in the directory
485
- structure.
486
-
487
-
488
- Autoloading Algorithms
489
- ----------------------
490
-
491
- ### Relative References
492
-
493
- A relative constant reference may appear in several places, for example, in
494
-
495
- ```ruby
496
- class PostsController < ApplicationController
497
- def index
498
- @posts = Post.all
499
- end
500
- end
501
- ```
502
-
503
- all three constant references are relative.
504
-
505
- #### Constants after the `class` and `module` Keywords
506
-
507
- Ruby performs a lookup for the constant that follows a `class` or `module`
508
- keyword because it needs to know if the class or module is going to be created
509
- or reopened.
510
-
511
- If the constant is not defined at that point it is not considered to be a
512
- missing constant, autoloading is **not** triggered.
513
-
514
- So, in the previous example, if `PostsController` is not defined when the file
515
- is interpreted Rails autoloading is not going to be triggered, Ruby will just
516
- define the controller.
517
-
518
- #### Top-Level Constants
519
-
520
- On the contrary, if `ApplicationController` is unknown, the constant is
521
- considered missing and an autoload is going to be attempted by Rails.
522
-
523
- In order to load `ApplicationController`, Rails iterates over `autoload_paths`.
524
- First checks if `app/assets/application_controller.rb` exists. If it does not,
525
- which is normally the case, it continues and finds
526
- `app/controllers/application_controller.rb`.
527
-
528
- If the file defines the constant `ApplicationController` all is fine, otherwise
529
- `LoadError` is raised:
530
-
531
- ```
532
- unable to autoload constant ApplicationController, expected
533
- <full path to application_controller.rb> to define it (LoadError)
534
- ```
535
-
536
- INFO. Rails does not require the value of autoloaded constants to be a class or
537
- module object. For example, if the file `app/models/max_clients.rb` defines
538
- `MAX_CLIENTS = 100` autoloading `MAX_CLIENTS` works just fine.
539
-
540
- #### Namespaces
541
-
542
- Autoloading `ApplicationController` looks directly under the directories of
543
- `autoload_paths` because the nesting in that spot is empty. The situation of
544
- `Post` is different, the nesting in that line is `[PostsController]` and support
545
- for namespaces comes into play.
546
-
547
- The basic idea is that given
548
-
549
- ```ruby
550
- module Admin
551
- class BaseController < ApplicationController
552
- @@all_roles = Role.all
553
- end
554
- end
555
- ```
556
-
557
- to autoload `Role` we are going to check if it is defined in the current or
558
- parent namespaces, one at a time. So, conceptually we want to try to autoload
559
- any of
560
-
561
- ```
562
- Admin::BaseController::Role
563
- Admin::Role
564
- Role
565
- ```
566
-
567
- in that order. That's the idea. To do so, Rails looks in `autoload_paths`
568
- respectively for file names like these:
569
-
570
- ```
571
- admin/base_controller/role.rb
572
- admin/role.rb
573
- role.rb
574
- ```
575
-
576
- modulus some additional directory lookups we are going to cover soon.
577
-
578
- INFO. `'Constant::Name'.underscore` gives the relative path without extension of
579
- the file name where `Constant::Name` is expected to be defined.
580
-
581
- Let's see how Rails autoloads the `Post` constant in the `PostsController`
582
- above assuming the application has a `Post` model defined in
583
- `app/models/post.rb`.
584
-
585
- First it checks for `posts_controller/post.rb` in `autoload_paths`:
586
-
587
- ```
588
- app/assets/posts_controller/post.rb
589
- app/controllers/posts_controller/post.rb
590
- app/helpers/posts_controller/post.rb
591
- ...
592
- test/mailers/previews/posts_controller/post.rb
593
- ```
594
-
595
- Since the lookup is exhausted without success, a similar search for a directory
596
- is performed, we are going to see why in the [next section](#automatic-modules):
597
-
598
- ```
599
- app/assets/posts_controller/post
600
- app/controllers/posts_controller/post
601
- app/helpers/posts_controller/post
602
- ...
603
- test/mailers/previews/posts_controller/post
604
- ```
605
-
606
- If all those attempts fail, then Rails starts the lookup again in the parent
607
- namespace. In this case only the top-level remains:
608
-
609
- ```
610
- app/assets/post.rb
611
- app/controllers/post.rb
612
- app/helpers/post.rb
613
- app/mailers/post.rb
614
- app/models/post.rb
615
- ```
616
-
617
- A matching file is found in `app/models/post.rb`. The lookup stops there and the
618
- file is loaded. If the file actually defines `Post` all is fine, otherwise
619
- `LoadError` is raised.
620
-
621
- ### Qualified References
622
-
623
- When a qualified constant is missing Rails does not look for it in the parent
624
- namespaces. But there is a caveat: When a constant is missing, Rails is
625
- unable to tell if the trigger was a relative reference or a qualified one.
626
-
627
- For example, consider
628
-
629
- ```ruby
630
- module Admin
631
- User
632
- end
633
- ```
634
-
635
- and
636
-
637
- ```ruby
638
- Admin::User
639
- ```
640
-
641
- If `User` is missing, in either case all Rails knows is that a constant called
642
- "User" was missing in a module called "Admin".
643
-
644
- If there is a top-level `User` Ruby would resolve it in the former example, but
645
- wouldn't in the latter. In general, Rails does not emulate the Ruby constant
646
- resolution algorithms, but in this case it tries using the following heuristic:
647
-
648
- > If none of the parent namespaces of the class or module has the missing
649
- > constant then Rails assumes the reference is relative. Otherwise qualified.
650
-
651
- For example, if this code triggers autoloading
652
-
653
- ```ruby
654
- Admin::User
655
- ```
656
-
657
- and the `User` constant is already present in `Object`, it is not possible that
658
- the situation is
659
-
660
- ```ruby
661
- module Admin
662
- User
663
- end
664
- ```
665
-
666
- because otherwise Ruby would have resolved `User` and no autoloading would have
667
- been triggered in the first place. Thus, Rails assumes a qualified reference and
668
- considers the file `admin/user.rb` and directory `admin/user` to be the only
669
- valid options.
670
-
671
- In practice, this works quite well as long as the nesting matches all parent
672
- namespaces respectively and the constants that make the rule apply are known at
673
- that time.
674
-
675
- However, autoloading happens on demand. If by chance the top-level `User` was
676
- not yet loaded, then Rails assumes a relative reference by contract.
677
-
678
- Naming conflicts of this kind are rare in practice, but if one occurs,
679
- `require_dependency` provides a solution by ensuring that the constant needed
680
- to trigger the heuristic is defined in the conflicting place.
681
-
682
- ### Automatic Modules
683
-
684
- When a module acts as a namespace, Rails does not require the application to
685
- defines a file for it, a directory matching the namespace is enough.
686
-
687
- Suppose an application has a back office whose controllers are stored in
688
- `app/controllers/admin`. If the `Admin` module is not yet loaded when
689
- `Admin::UsersController` is hit, Rails needs first to autoload the constant
690
- `Admin`.
691
-
692
- If `autoload_paths` has a file called `admin.rb` Rails is going to load that
693
- one, but if there's no such file and a directory called `admin` is found, Rails
694
- creates an empty module and assigns it to the `Admin` constant on the fly.
695
-
696
- ### Generic Procedure
697
-
698
- Relative references are reported to be missing in the cref where they were hit,
699
- and qualified references are reported to be missing in their parent (see
700
- [Resolution Algorithm for Relative
701
- Constants](#resolution-algorithm-for-relative-constants) at the beginning of
702
- this guide for the definition of *cref*, and [Resolution Algorithm for Qualified
703
- Constants](#resolution-algorithm-for-qualified-constants) for the definition of
704
- *parent*).
705
-
706
- The procedure to autoload constant `C` in an arbitrary situation is as follows:
707
-
708
- ```
709
- if the class or module in which C is missing is Object
710
- let ns = ''
711
- else
712
- let M = the class or module in which C is missing
713
-
714
- if M is anonymous
715
- let ns = ''
716
- else
717
- let ns = M.name
718
- end
719
- end
720
-
721
- loop do
722
- # Look for a regular file.
723
- for dir in autoload_paths
724
- if the file "#{dir}/#{ns.underscore}/c.rb" exists
725
- load/require "#{dir}/#{ns.underscore}/c.rb"
726
-
727
- if C is now defined
728
- return
729
- else
730
- raise LoadError
731
- end
732
- end
733
- end
734
-
735
- # Look for an automatic module.
736
- for dir in autoload_paths
737
- if the directory "#{dir}/#{ns.underscore}/c" exists
738
- if ns is an empty string
739
- let C = Module.new in Object and return
740
- else
741
- let C = Module.new in ns.constantize and return
742
- end
743
- end
744
- end
745
-
746
- if ns is empty
747
- # We reached the top-level without finding the constant.
748
- raise NameError
749
- else
750
- if C exists in any of the parent namespaces
751
- # Qualified constants heuristic.
752
- raise NameError
753
- else
754
- # Try again in the parent namespace.
755
- let ns = the parent namespace of ns and retry
756
- end
757
- end
758
- end
759
- ```
760
-
761
-
762
- require_dependency
763
- ------------------
764
-
765
- Constant autoloading is triggered on demand and therefore code that uses a
766
- certain constant may have it already defined or may trigger an autoload. That
767
- depends on the execution path and it may vary between runs.
768
-
769
- There are times, however, in which you want to make sure a certain constant is
770
- known when the execution reaches some code. `require_dependency` provides a way
771
- to load a file using the current [loading mechanism](#loading-mechanism), and
772
- keeping track of constants defined in that file as if they were autoloaded to
773
- have them reloaded as needed.
774
-
775
- `require_dependency` is rarely needed, but see a couple of use-cases in
776
- [Autoloading and STI](#autoloading-and-sti) and [When Constants aren't
777
- Triggered](#when-constants-aren-t-missed).
778
-
779
- WARNING. Unlike autoloading, `require_dependency` does not expect the file to
780
- define any particular constant. Exploiting this behavior would be a bad practice
781
- though, file and constant paths should match.
782
-
783
-
784
- Constant Reloading
785
- ------------------
786
-
787
- When `config.cache_classes` is false Rails is able to reload autoloaded
788
- constants.
789
-
790
- For example, in you're in a console session and edit some file behind the
791
- scenes, the code can be reloaded with the `reload!` command:
792
-
793
- ```
794
- > reload!
795
- ```
796
-
797
- When the application runs, code is reloaded when something relevant to this
798
- logic changes. In order to do that, Rails monitors a number of things:
799
-
800
- * `config/routes.rb`.
801
-
802
- * Locales.
803
-
804
- * Ruby files under `autoload_paths`.
805
-
806
- * `db/schema.rb` and `db/structure.sql`.
807
-
808
- If anything in there changes, there is a middleware that detects it and reloads
809
- the code.
810
-
811
- Autoloading keeps track of autoloaded constants. Reloading is implemented by
812
- removing them all from their respective classes and modules using
813
- `Module#remove_const`. That way, when the code goes on, those constants are
814
- going to be unknown again, and files reloaded on demand.
815
-
816
- INFO. This is an all-or-nothing operation, Rails does not attempt to reload only
817
- what changed since dependencies between classes makes that really tricky.
818
- Instead, everything is wiped.
819
-
820
-
821
- Module#autoload isn't Involved
822
- ------------------------------
823
-
824
- `Module#autoload` provides a lazy way to load constants that is fully integrated
825
- with the Ruby constant lookup algorithms, dynamic constant API, etc. It is quite
826
- transparent.
827
-
828
- Rails internals make extensive use of it to defer as much work as possible from
829
- the boot process. But constant autoloading in Rails is **not** implemented with
830
- `Module#autoload`.
831
-
832
- One possible implementation based on `Module#autoload` would be to walk the
833
- application tree and issue `autoload` calls that map existing file names to
834
- their conventional constant name.
835
-
836
- There are a number of reasons that prevent Rails from using that implementation.
837
-
838
- For example, `Module#autoload` is only capable of loading files using `require`,
839
- so reloading would not be possible. Not only that, it uses an internal `require`
840
- which is not `Kernel#require`.
841
-
842
- Then, it provides no way to remove declarations in case a file is deleted. If a
843
- constant gets removed with `Module#remove_const` its `autoload` is not triggered
844
- again. Also, it doesn't support qualified names, so files with namespaces should
845
- be interpreted during the walk tree to install their own `autoload` calls, but
846
- those files could have constant references not yet configured.
847
-
848
- An implementation based on `Module#autoload` would be awesome but, as you see,
849
- at least as of today it is not possible. Constant autoloading in Rails is
850
- implemented with `Module#const_missing`, and that's why it has its own contract,
851
- documented in this guide.
852
-
853
-
854
- Common Gotchas
855
- --------------
856
-
857
- ### Nesting and Qualified Constants
858
-
859
- Let's consider
860
-
861
- ```ruby
862
- module Admin
863
- class UsersController < ApplicationController
864
- def index
865
- @users = User.all
866
- end
867
- end
868
- end
869
- ```
870
-
871
- and
872
-
873
- ```ruby
874
- class Admin::UsersController < ApplicationController
875
- def index
876
- @users = User.all
877
- end
878
- end
879
- ```
880
-
881
- To resolve `User` Ruby checks `Admin` in the former case, but it does not in
882
- the latter because it does not belong to the nesting (see [Nesting](#nesting)
883
- and [Resolution Algorithms](#resolution-algorithms)).
884
-
885
- Unfortunately Rails autoloading does not know the nesting in the spot where the
886
- constant was missing and so it is not able to act as Ruby would. In particular,
887
- `Admin::User` will get autoloaded in either case.
888
-
889
- Albeit qualified constants with `class` and `module` keywords may technically
890
- work with autoloading in some cases, it is preferable to use relative constants
891
- instead:
892
-
893
- ```ruby
894
- module Admin
895
- class UsersController < ApplicationController
896
- def index
897
- @users = User.all
898
- end
899
- end
900
- end
901
- ```
902
-
903
- ### Autoloading and STI
904
-
905
- Single Table Inheritance (STI) is a feature of Active Record that enables
906
- storing a hierarchy of models in one single table. The API of such models is
907
- aware of the hierarchy and encapsulates some common needs. For example, given
908
- these classes:
909
-
910
- ```ruby
911
- # app/models/polygon.rb
912
- class Polygon < ActiveRecord::Base
913
- end
914
-
915
- # app/models/triangle.rb
916
- class Triangle < Polygon
917
- end
918
-
919
- # app/models/rectangle.rb
920
- class Rectangle < Polygon
921
- end
922
- ```
923
-
924
- `Triangle.create` creates a row that represents a triangle, and
925
- `Rectangle.create` creates a row that represents a rectangle. If `id` is the
926
- ID of an existing record, `Polygon.find(id)` returns an object of the correct
927
- type.
928
-
929
- Methods that operate on collections are also aware of the hierarchy. For
930
- example, `Polygon.all` returns all the records of the table, because all
931
- rectangles and triangles are polygons. Active Record takes care of returning
932
- instances of their corresponding class in the result set.
933
-
934
- Types are autoloaded as needed. For example, if `Polygon.first` is a rectangle
935
- and `Rectangle` has not yet been loaded, Active Record autoloads it and the
936
- record is correctly instantiated.
937
-
938
- All good, but if instead of performing queries based on the root class we need
939
- to work on some subclass, things get interesting.
940
-
941
- While working with `Polygon` you do not need to be aware of all its descendants,
942
- because anything in the table is by definition a polygon, but when working with
943
- subclasses Active Record needs to be able to enumerate the types it is looking
944
- for. Let’s see an example.
945
-
946
- `Rectangle.all` only loads rectangles by adding a type constraint to the query:
947
-
948
- ```sql
949
- SELECT "polygons".* FROM "polygons"
950
- WHERE "polygons"."type" IN ("Rectangle")
951
- ```
952
-
953
- Let’s introduce now a subclass of `Rectangle`:
954
-
955
- ```ruby
956
- # app/models/square.rb
957
- class Square < Rectangle
958
- end
959
- ```
960
-
961
- `Rectangle.all` should now return rectangles **and** squares:
962
-
963
- ```sql
964
- SELECT "polygons".* FROM "polygons"
965
- WHERE "polygons"."type" IN ("Rectangle", "Square")
966
- ```
967
-
968
- But there’s a caveat here: How does Active Record know that the class `Square`
969
- exists at all?
970
-
971
- Even if the file `app/models/square.rb` exists and defines the `Square` class,
972
- if no code yet used that class, `Rectangle.all` issues the query
973
-
974
- ```sql
975
- SELECT "polygons".* FROM "polygons"
976
- WHERE "polygons"."type" IN ("Rectangle")
977
- ```
978
-
979
- That is not a bug, the query includes all *known* descendants of `Rectangle`.
980
-
981
- A way to ensure this works correctly regardless of the order of execution is to
982
- load the leaves of the tree by hand at the bottom of the file that defines the
983
- root class:
984
-
985
- ```ruby
986
- # app/models/polygon.rb
987
- class Polygon < ActiveRecord::Base
988
- end
989
- require_dependency ‘square’
990
- ```
991
-
992
- Only the leaves that are **at least grandchildren** need to be loaded this
993
- way. Direct subclasses do not need to be preloaded. If the hierarchy is
994
- deeper, intermediate classes will be autoloaded recursively from the bottom
995
- because their constant will appear in the class definitions as superclass.
996
-
997
- ### Autoloading and `require`
998
-
999
- Files defining constants to be autoloaded should never be `require`d:
1000
-
1001
- ```ruby
1002
- require 'user' # DO NOT DO THIS
1003
-
1004
- class UsersController < ApplicationController
1005
- ...
1006
- end
1007
- ```
1008
-
1009
- There are two possible gotchas here in development mode:
1010
-
1011
- 1. If `User` is autoloaded before reaching the `require`, `app/models/user.rb`
1012
- runs again because `load` does not update `$LOADED_FEATURES`.
1013
-
1014
- 2. If the `require` runs first Rails does not mark `User` as an autoloaded
1015
- constant and changes to `app/models/user.rb` aren't reloaded.
1016
-
1017
- Just follow the flow and use constant autoloading always, never mix
1018
- autoloading and `require`. As a last resort, if some file absolutely needs to
1019
- load a certain file use `require_dependency` to play nice with constant
1020
- autoloading. This option is rarely needed in practice, though.
1021
-
1022
- Of course, using `require` in autoloaded files to load ordinary 3rd party
1023
- libraries is fine, and Rails is able to distinguish their constants, they are
1024
- not marked as autoloaded.
1025
-
1026
- ### Autoloading and Initializers
1027
-
1028
- Consider this assignment in `config/initializers/set_auth_service.rb`:
1029
-
1030
- ```ruby
1031
- AUTH_SERVICE = if Rails.env.production?
1032
- RealAuthService
1033
- else
1034
- MockedAuthService
1035
- end
1036
- ```
1037
-
1038
- The purpose of this setup would be that the application uses the class that
1039
- corresponds to the environment via `AUTH_SERVICE`. In development mode
1040
- `MockedAuthService` gets autoloaded when the initializer runs. Let’s suppose
1041
- we do some requests, change its implementation, and hit the application again.
1042
- To our surprise the changes are not reflected. Why?
1043
-
1044
- As [we saw earlier](#constant-reloading), Rails removes autoloaded constants,
1045
- but `AUTH_SERVICE` stores the original class object. Stale, non-reachable
1046
- using the original constant, but perfectly functional.
1047
-
1048
- The following code summarizes the situation:
1049
-
1050
- ```ruby
1051
- class C
1052
- def quack
1053
- 'quack!'
1054
- end
1055
- end
1056
-
1057
- X = C
1058
- Object.instance_eval { remove_const(:C) }
1059
- X.new.quack # => quack!
1060
- X.name # => C
1061
- C # => uninitialized constant C (NameError)
1062
- ```
1063
-
1064
- Because of that, it is not a good idea to autoload constants on application
1065
- initialization.
1066
-
1067
- In the case above we could implement a dynamic access point:
1068
-
1069
- ```ruby
1070
- # app/models/auth_service.rb
1071
- class AuthService
1072
- if Rails.env.production?
1073
- def self.instance
1074
- RealAuthService
1075
- end
1076
- else
1077
- def self.instance
1078
- MockedAuthService
1079
- end
1080
- end
1081
- end
1082
- ```
1083
-
1084
- and have the application use `AuthService.instance` instead. `AuthService`
1085
- would be loaded on demand and be autoload-friendly.
1086
-
1087
- ### `require_dependency` and Initializers
1088
-
1089
- As we saw before, `require_dependency` loads files in an autoloading-friendly
1090
- way. Normally, though, such a call does not make sense in an initializer.
1091
-
1092
- One could think about doing some [`require_dependency`](#require-dependency)
1093
- calls in an initializer to make sure certain constants are loaded upfront, for
1094
- example as an attempt to address the [gotcha with STIs](#autoloading-and-sti).
1095
-
1096
- Problem is, in development mode [autoloaded constants are wiped](#constant-reloading)
1097
- if there is any relevant change in the file system. If that happens then
1098
- we are in the very same situation the initializer wanted to avoid!
1099
-
1100
- Calls to `require_dependency` have to be strategically written in autoloaded
1101
- spots.
1102
-
1103
- ### When Constants aren't Missed
1104
-
1105
- #### Relative References
1106
-
1107
- Let's consider a flight simulator. The application has a default flight model
1108
-
1109
- ```ruby
1110
- # app/models/flight_model.rb
1111
- class FlightModel
1112
- end
1113
- ```
1114
-
1115
- that can be overridden by each airplane, for instance
1116
-
1117
- ```ruby
1118
- # app/models/bell_x1/flight_model.rb
1119
- module BellX1
1120
- class FlightModel < FlightModel
1121
- end
1122
- end
1123
-
1124
- # app/models/bell_x1/aircraft.rb
1125
- module BellX1
1126
- class Aircraft
1127
- def initialize
1128
- @flight_model = FlightModel.new
1129
- end
1130
- end
1131
- end
1132
- ```
1133
-
1134
- The initializer wants to create a `BellX1::FlightModel` and nesting has
1135
- `BellX1`, that looks good. But if the default flight model is loaded and the
1136
- one for the Bell-X1 is not, the interpreter is able to resolve the top-level
1137
- `FlightModel` and autoloading is thus not triggered for `BellX1::FlightModel`.
1138
-
1139
- That code depends on the execution path.
1140
-
1141
- These kind of ambiguities can often be resolved using qualified constants:
1142
-
1143
- ```ruby
1144
- module BellX1
1145
- class Plane
1146
- def flight_model
1147
- @flight_model ||= BellX1::FlightModel.new
1148
- end
1149
- end
1150
- end
1151
- ```
1152
-
1153
- Also, `require_dependency` is a solution:
1154
-
1155
- ```ruby
1156
- require_dependency 'bell_x1/flight_model'
1157
-
1158
- module BellX1
1159
- class Plane
1160
- def flight_model
1161
- @flight_model ||= FlightModel.new
1162
- end
1163
- end
1164
- end
1165
- ```
1166
-
1167
- #### Qualified References
1168
-
1169
- Given
1170
-
1171
- ```ruby
1172
- # app/models/hotel.rb
1173
- class Hotel
1174
- end
1175
-
1176
- # app/models/image.rb
1177
- class Image
1178
- end
1179
-
1180
- # app/models/hotel/image.rb
1181
- class Hotel
1182
- class Image < Image
1183
- end
1184
- end
1185
- ```
1186
-
1187
- the expression `Hotel::Image` is ambiguous because it depends on the execution
1188
- path.
1189
-
1190
- As [we saw before](#resolution-algorithm-for-qualified-constants), Ruby looks
1191
- up the constant in `Hotel` and its ancestors. If `app/models/image.rb` has
1192
- been loaded but `app/models/hotel/image.rb` hasn't, Ruby does not find `Image`
1193
- in `Hotel`, but it does in `Object`:
1194
-
1195
- ```
1196
- $ bin/rails r 'Image; p Hotel::Image' 2>/dev/null
1197
- Image # NOT Hotel::Image!
1198
- ```
1199
-
1200
- The code evaluating `Hotel::Image` needs to make sure
1201
- `app/models/hotel/image.rb` has been loaded, possibly with
1202
- `require_dependency`.
1203
-
1204
- In these cases the interpreter issues a warning though:
1205
-
1206
- ```
1207
- warning: toplevel constant Image referenced by Hotel::Image
1208
- ```
1209
-
1210
- This surprising constant resolution can be observed with any qualifying class:
1211
-
1212
- ```
1213
- 2.1.5 :001 > String::Array
1214
- (irb):1: warning: toplevel constant Array referenced by String::Array
1215
- => Array
1216
- ```
1217
-
1218
- WARNING. To find this gotcha the qualifying namespace has to be a class,
1219
- `Object` is not an ancestor of modules.
1220
-
1221
- ### Autoloading within Singleton Classes
1222
-
1223
- Let's suppose we have these class definitions:
1224
-
1225
- ```ruby
1226
- # app/models/hotel/services.rb
1227
- module Hotel
1228
- class Services
1229
- end
1230
- end
1231
-
1232
- # app/models/hotel/geo_location.rb
1233
- module Hotel
1234
- class GeoLocation
1235
- class << self
1236
- Services
1237
- end
1238
- end
1239
- end
1240
- ```
1241
-
1242
- If `Hotel::Services` is known by the time `app/models/hotel/geo_location.rb`
1243
- is being loaded, `Services` is resolved by Ruby because `Hotel` belongs to the
1244
- nesting when the singleton class of `Hotel::GeoLocation` is opened.
1245
-
1246
- But if `Hotel::Services` is not known, Rails is not able to autoload it, the
1247
- application raises `NameError`.
1248
-
1249
- The reason is that autoloading is triggered for the singleton class, which is
1250
- anonymous, and as [we saw before](#generic-procedure), Rails only checks the
1251
- top-level namespace in that edge case.
1252
-
1253
- An easy solution to this caveat is to qualify the constant:
1254
-
1255
- ```ruby
1256
- module Hotel
1257
- class GeoLocation
1258
- class << self
1259
- Hotel::Services
1260
- end
1261
- end
1262
- end
1263
- ```
1264
-
1265
- ### Autoloading in `BasicObject`
1266
-
1267
- Direct descendants of `BasicObject` do not have `Object` among their ancestors
1268
- and cannot resolve top-level constants:
1269
-
1270
- ```ruby
1271
- class C < BasicObject
1272
- String # NameError: uninitialized constant C::String
1273
- end
1274
- ```
1275
-
1276
- When autoloading is involved that plot has a twist. Let's consider:
1277
-
1278
- ```ruby
1279
- class C < BasicObject
1280
- def user
1281
- User # WRONG
1282
- end
1283
- end
1284
- ```
1285
-
1286
- Since Rails checks the top-level namespace `User` gets autoloaded just fine the
1287
- first time the `user` method is invoked. You only get the exception if the
1288
- `User` constant is known at that point, in particular in a *second* call to
1289
- `user`:
1290
-
1291
- ```ruby
1292
- c = C.new
1293
- c.user # surprisingly fine, User
1294
- c.user # NameError: uninitialized constant C::User
1295
- ```
1296
-
1297
- because it detects that a parent namespace already has the constant (see [Qualified
1298
- References](#autoloading-algorithms-qualified-references)).
1299
-
1300
- As with pure Ruby, within the body of a direct descendant of `BasicObject` use
1301
- always absolute constant paths:
1302
-
1303
- ```ruby
1304
- class C < BasicObject
1305
- ::String # RIGHT
1306
-
1307
- def user
1308
- ::User # RIGHT
1309
- end
1310
- end
1311
- ```