You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guides/source/autoloading_and_reloading_constants.md
+51-12Lines changed: 51 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -176,7 +176,7 @@ Reloading
176
176
177
177
Rails automatically reloads classes and modules if application files in the autoload paths change.
178
178
179
-
More precisely, if the web server is running and application files have been modified, Rails unloads all autoloaded constants just before the next request is processed. That way, application classes or modules used during that request will be autoloaded again, thus picking up their current implementation in the file system.
179
+
More precisely, if the web server is running and application files have been modified, Rails unloads all autoloaded constants managed by the `main` autoloader just before the next request is processed. That way, application classes or modules used during that request will be autoloaded again, thus picking up their current implementation in the file system.
180
180
181
181
Reloading can be enabled or disabled. The setting that controls this behavior is `config.cache_classes`, which is false by default in `development` mode (reloading enabled), and true by default in `production` mode (reloading disabled).
182
182
@@ -226,34 +226,73 @@ if `User` is reloaded, since `VipUser` is not, the superclass of `VipUser` is th
226
226
227
227
Bottom line: **do not cache reloadable classes or modules**.
228
228
229
-
###Autoloading when the application boots
229
+
## Autoloading when the application boots
230
230
231
-
Applications can safely autoload constants during boot using a reloader callback:
231
+
While booting, applications can autoload from the autoload once paths, which are managed by the `once` autoloader. Please check the section [`config.autoload_once_paths`](#config-autoload-once-paths) above.
232
+
233
+
However, you cannot autoload from the autoload paths, which are managed by the `main` autoloader. This applies to code in `config/initializers` as well as application or engines initializers.
234
+
235
+
Why? Initializers only run once, when the application boots. If you reboot the server, they run again in a new process, but reloading does not reboot the server, and initializers don't run again. Let's see the two main use cases.
236
+
237
+
### Use case 1: During boot, load reloadable code
238
+
239
+
Let's imagine `ApiGateway` is a reloadable class from `app/services` managed by the `main` autoloader and you need to configure its endpoint while the application boots:
232
240
233
241
```ruby
242
+
# config/initializers/api_gateway_setup.rb
243
+
ApiGateway.endpoint ="https://example.com"# DO NOT DO THIS
244
+
```
245
+
246
+
a reloaded `ApiGateway` would have a `nil` endpoint, because the code above does not run again.
247
+
248
+
You can still set things up during boot, but you need to wrap them in a `to_prepare` block, which is runs on boot, and after each reload:
That block runs when the application boots, and every time code is reloaded.
240
-
241
257
NOTE: For historical reasons, this callback may run twice. The code it executes must be idempotent.
242
258
243
-
However, if you do not need to reload the class, it is easier to define it in a directory which does not belong to the autoload paths. For instance, `lib` is an idiomatic choice. It does not belong to the autoload paths by default, but it does belong to `$LOAD_PATH`. Then, in the place the class is needed at boot time, just perform a regular `require` to load it.
259
+
### Use case 2: During boot, load code that remains cached
244
260
245
-
For example, there is no point in defining reloadable Rack middleware, because changes would not be reflected in the instance stored in the middleware stack anyway. If `lib/my_app/middleware/foo.rb` defines a middleware class, then in `config/application.rb` you write:
261
+
Some configurations take a class or module object, and they store it in a place that is not reloaded, for example, within the state of the framework.
262
+
263
+
One example is middleware:
246
264
247
265
```ruby
248
-
require"my_app/middleware/foo"
249
-
...
250
266
config.middleware.use MyApp::Middleware::Foo
251
267
```
252
268
253
-
To have changes in that middleware reflected, you need to restart the server.
269
+
When you reload, the middleware stack is not affected, so, whatever object was stored in `MyApp::Middleware::Foo` at boot time remains there stale.
Whatever `MoneySerializer` evaluates to during initialization gets pushed to the custom serializers. If that was reloadable, the initial object would be still within Active Job, not reflecting your changes.
279
+
280
+
Corollary: those classes or modules **cannot be reloadable**.
281
+
282
+
The easiest way to refer to those classes or modules during boot is to have them defined in a directory which does not belong to the autoload paths. For instance, `lib` is an idiomatic choice. It does not belong to the autoload paths by default, but it does belong to `$LOAD_PATH`. Just perform a regular `require` to load it and done.
254
283
255
-
Another possibility is to autoload from the autoload once paths. Please check the section [`config.autoload_once_paths`](#config-autoload-once-paths) above.
284
+
As noted above, another option is to have the directory that defines them in the autoload once paths:
0 commit comments