rails 4.2.6.rc1 → 5.2.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (218) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +24 -12
  3. metadata +54 -248
  4. data/guides/CHANGELOG.md +0 -73
  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/generator.rb +0 -248
  150. data/guides/rails_guides/helpers.rb +0 -53
  151. data/guides/rails_guides/indexer.rb +0 -68
  152. data/guides/rails_guides/kindle.rb +0 -119
  153. data/guides/rails_guides/levenshtein.rb +0 -37
  154. data/guides/rails_guides/markdown/renderer.rb +0 -82
  155. data/guides/rails_guides/markdown.rb +0 -167
  156. data/guides/rails_guides.rb +0 -63
  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 -1227
  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
- ```