railties 6.1.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -276
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +16 -16
  5. data/README.rdoc +1 -2
  6. data/lib/rails/all.rb +0 -1
  7. data/lib/rails/api/task.rb +1 -1
  8. data/lib/rails/app_updater.rb +3 -5
  9. data/lib/rails/application/bootstrap.rb +21 -5
  10. data/lib/rails/application/configuration.rb +79 -33
  11. data/lib/rails/application/default_middleware_stack.rb +7 -3
  12. data/lib/rails/application/finisher.rb +42 -85
  13. data/lib/rails/application/routes_reloader.rb +8 -0
  14. data/lib/rails/application.rb +32 -51
  15. data/lib/rails/application_controller.rb +2 -2
  16. data/lib/rails/autoloaders/inflector.rb +21 -0
  17. data/lib/rails/autoloaders.rb +12 -16
  18. data/lib/rails/code_statistics.rb +2 -2
  19. data/lib/rails/code_statistics_calculator.rb +10 -1
  20. data/lib/rails/command/base.rb +26 -12
  21. data/lib/rails/command/behavior.rb +1 -1
  22. data/lib/rails/command/environment_argument.rb +1 -1
  23. data/lib/rails/command.rb +11 -10
  24. data/lib/rails/commands/credentials/USAGE +4 -2
  25. data/lib/rails/commands/credentials/credentials_command/diffing.rb +26 -16
  26. data/lib/rails/commands/credentials/credentials_command.rb +8 -3
  27. data/lib/rails/commands/dbconsole/dbconsole_command.rb +10 -11
  28. data/lib/rails/commands/help/USAGE +3 -2
  29. data/lib/rails/commands/notes/notes_command.rb +2 -2
  30. data/lib/rails/commands/runner/runner_command.rb +3 -2
  31. data/lib/rails/commands/server/server_command.rb +2 -5
  32. data/lib/rails/configuration.rb +18 -23
  33. data/lib/rails/engine/configuration.rb +3 -3
  34. data/lib/rails/engine.rb +18 -24
  35. data/lib/rails/gem_version.rb +2 -2
  36. data/lib/rails/generators/actions/create_migration.rb +4 -4
  37. data/lib/rails/generators/actions.rb +35 -13
  38. data/lib/rails/generators/app_base.rb +140 -102
  39. data/lib/rails/generators/app_name.rb +1 -1
  40. data/lib/rails/generators/base.rb +9 -13
  41. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +2 -0
  42. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +8 -8
  43. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +8 -4
  44. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +11 -28
  45. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +7 -3
  46. data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +17 -0
  47. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +8 -17
  48. data/lib/rails/generators/erb.rb +1 -1
  49. data/lib/rails/generators/generated_attribute.rb +45 -9
  50. data/lib/rails/generators/migration.rb +2 -6
  51. data/lib/rails/generators/model_helpers.rb +1 -1
  52. data/lib/rails/generators/named_base.rb +11 -11
  53. data/lib/rails/generators/rails/app/app_generator.rb +54 -93
  54. data/lib/rails/generators/rails/app/templates/Gemfile.tt +42 -52
  55. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +2 -2
  56. data/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt +2 -2
  57. data/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt +1 -1
  58. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +3 -9
  59. data/lib/rails/generators/rails/app/templates/bin/rails.tt +1 -4
  60. data/lib/rails/generators/rails/app/templates/bin/rake.tt +0 -3
  61. data/lib/rails/generators/rails/app/templates/bin/setup.tt +9 -14
  62. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +0 -1
  63. data/lib/rails/generators/rails/app/templates/config/boot.rb.tt +1 -1
  64. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +2 -2
  65. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +3 -3
  67. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +2 -2
  68. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  69. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +2 -2
  70. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +3 -3
  71. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  72. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +5 -5
  73. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +6 -12
  74. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +11 -38
  75. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +6 -11
  76. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -5
  77. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +19 -25
  78. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +2 -2
  79. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt +4 -4
  80. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +117 -0
  81. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +3 -3
  82. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +1 -1
  83. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -1
  84. data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +5 -5
  85. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +2 -2
  86. data/lib/rails/generators/rails/app/templates/gitattributes.tt +0 -5
  87. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -1
  88. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  89. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -2
  90. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +0 -4
  91. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  92. data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -1
  93. data/lib/rails/generators/rails/plugin/plugin_generator.rb +42 -24
  94. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +7 -3
  95. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +11 -20
  96. data/lib/rails/generators/rails/plugin/templates/README.md.tt +1 -1
  97. data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +2 -2
  98. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +0 -3
  99. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +4 -5
  100. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -5
  101. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +2 -2
  102. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt +1 -1
  103. data/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt +2 -2
  104. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -7
  105. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +0 -19
  106. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -5
  107. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +6 -10
  108. data/lib/rails/generators/resource_helpers.rb +2 -2
  109. data/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt +1 -1
  110. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
  111. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +3 -3
  112. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +5 -5
  113. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +7 -7
  114. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +9 -11
  115. data/lib/rails/generators/testing/behaviour.rb +3 -4
  116. data/lib/rails/generators.rb +9 -22
  117. data/lib/rails/info.rb +1 -1
  118. data/lib/rails/info_controller.rb +1 -3
  119. data/lib/rails/initializable.rb +1 -1
  120. data/lib/rails/mailers_controller.rb +2 -4
  121. data/lib/rails/rack/logger.rb +0 -1
  122. data/lib/rails/railtie/configuration.rb +1 -2
  123. data/lib/rails/railtie.rb +31 -14
  124. data/lib/rails/ruby_version_check.rb +3 -3
  125. data/lib/rails/secrets.rb +4 -1
  126. data/lib/rails/source_annotation_extractor.rb +1 -1
  127. data/lib/rails/tasks/framework.rake +2 -8
  128. data/lib/rails/tasks/statistics.rake +3 -1
  129. data/lib/rails/tasks/tmp.rake +8 -1
  130. data/lib/rails/tasks/yarn.rake +10 -7
  131. data/lib/rails/tasks/zeitwerk.rake +2 -10
  132. data/lib/rails/templates/layouts/application.html.erb +15 -0
  133. data/lib/rails/templates/rails/mailers/email.html.erb +13 -11
  134. data/lib/rails/templates/rails/welcome/index.html.erb +62 -47
  135. data/lib/rails/test_unit/railtie.rb +0 -4
  136. data/lib/rails/test_unit/runner.rb +16 -9
  137. data/lib/rails/test_unit/testing.rake +4 -9
  138. data/lib/rails/welcome_controller.rb +1 -0
  139. data/lib/rails.rb +5 -0
  140. metadata +33 -36
  141. data/lib/rails/command/spellchecker.rb +0 -57
  142. data/lib/rails/generators/css/assets/assets_generator.rb +0 -15
  143. data/lib/rails/generators/css/assets/templates/stylesheet.css +0 -4
  144. data/lib/rails/generators/css/scaffold/scaffold_generator.rb +0 -18
  145. data/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js +0 -6
  146. data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +0 -5
  147. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +0 -23
  148. data/lib/rails/generators/rails/app/templates/bin/spring.tt +0 -9
  149. data/lib/rails/generators/rails/app/templates/bin/yarn.tt +0 -18
  150. data/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt +0 -8
  151. data/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt +0 -8
  152. data/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt +0 -5
  153. data/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb.tt +0 -4
  154. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_1.rb.tt +0 -63
  155. data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +0 -16
  156. data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +0 -6
  157. data/lib/rails/generators/rails/app/templates/package.json.tt +0 -11
  158. data/lib/rails/generators/rails/assets/USAGE +0 -16
  159. data/lib/rails/generators/rails/assets/assets_generator.rb +0 -26
  160. data/lib/rails/generators/rails/assets/templates/stylesheet.css +0 -4
  161. data/lib/rails/generators/rails/scaffold/templates/scaffold.css +0 -80
@@ -14,6 +14,7 @@ module Rails
14
14
  initializer :load_environment_hook, group: :all do end
15
15
 
16
16
  initializer :load_active_support, group: :all do
17
+ ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"] = "true" if config.active_support.disable_to_s_conversion
17
18
  require "active_support/all" unless config.active_support.bare
18
19
  end
19
20
 
@@ -44,13 +45,16 @@ module Rails
44
45
  logger.level = ActiveSupport::Logger::WARN
45
46
  logger.warn(
46
47
  "Rails Error: Unable to access log file. Please ensure that #{path} exists and is writable " \
47
- "(ie, make it writable for user and group: chmod 0664 #{path}). " \
48
+ "(i.e. make it writable for user and group: chmod 0664 #{path}). " \
48
49
  "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
49
50
  )
50
51
  logger
51
52
  end
52
-
53
53
  Rails.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase)
54
+
55
+ unless config.consider_all_requests_local
56
+ Rails.error.logger = Rails.logger
57
+ end
54
58
  end
55
59
 
56
60
  # Initialize cache early in the stack so railties can make use of it.
@@ -64,9 +68,21 @@ module Rails
64
68
  end
65
69
  end
66
70
 
67
- # Sets the dependency loading mechanism.
68
- initializer :initialize_dependency_mechanism, group: :all do
69
- ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
71
+ # We setup the once autoloader this early so that engines and applications
72
+ # are able to autoload from these paths during initialization.
73
+ initializer :setup_once_autoloader, after: :set_eager_load_paths, before: :bootstrap_hook do
74
+ autoloader = Rails.autoloaders.once
75
+
76
+ ActiveSupport::Dependencies.autoload_once_paths.freeze
77
+ ActiveSupport::Dependencies.autoload_once_paths.uniq.each do |path|
78
+ # Zeitwerk only accepts existing directories in `push_dir`.
79
+ next unless File.directory?(path)
80
+
81
+ autoloader.push_dir(path)
82
+ autoloader.do_not_eager_load(path) unless ActiveSupport::Dependencies.eager_load?(path)
83
+ end
84
+
85
+ autoloader.setup
70
86
  end
71
87
 
72
88
  initializer :bootstrap_hook, group: :all do |app|
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "ipaddr"
4
4
  require "active_support/core_ext/kernel/reporting"
5
- require "active_support/core_ext/symbol/starts_ends_with"
6
5
  require "active_support/file_update_checker"
7
6
  require "active_support/configuration_file"
8
7
  require "rails/engine/configuration"
@@ -22,9 +21,9 @@ module Rails
22
21
  :read_encrypted_secrets, :log_level, :content_security_policy_report_only,
23
22
  :content_security_policy_nonce_generator, :content_security_policy_nonce_directives,
24
23
  :require_master_key, :credentials, :disable_sandbox, :add_autoload_paths_to_load_path,
25
- :rake_eager_load
24
+ :rake_eager_load, :server_timing
26
25
 
27
- attr_reader :encoding, :api_only, :loaded_config_version, :autoloader
26
+ attr_reader :encoding, :api_only, :loaded_config_version
28
27
 
29
28
  def initialize(*)
30
29
  super
@@ -34,7 +33,12 @@ module Rails
34
33
  @filter_parameters = []
35
34
  @filter_redirect = []
36
35
  @helpers_paths = []
37
- @hosts = Array(([".localhost", IPAddr.new("0.0.0.0/0"), IPAddr.new("::/0")] if Rails.env.development?))
36
+ if Rails.env.development?
37
+ @hosts = ActionDispatch::HostAuthorization::ALLOWED_HOSTS_IN_DEVELOPMENT +
38
+ ENV["RAILS_DEVELOPMENT_HOSTS"].to_s.split(",").map(&:strip)
39
+ else
40
+ @hosts = []
41
+ end
38
42
  @host_authorization = {}
39
43
  @public_file_server = ActiveSupport::OrderedOptions.new
40
44
  @public_file_server.enabled = true
@@ -70,11 +74,11 @@ module Rails
70
74
  @credentials = ActiveSupport::OrderedOptions.new
71
75
  @credentials.content_path = default_credentials_content_path
72
76
  @credentials.key_path = default_credentials_key_path
73
- @autoloader = :classic
74
77
  @disable_sandbox = false
75
78
  @add_autoload_paths_to_load_path = true
76
79
  @permissions_policy = nil
77
80
  @rake_eager_load = false
81
+ @server_timing = false
78
82
  end
79
83
 
80
84
  # Loads default configurations. See {the result of the method for each version}[https://guides.rubyonrails.org/configuring.html#results-of-config-load-defaults].
@@ -84,6 +88,7 @@ module Rails
84
88
  if respond_to?(:action_controller)
85
89
  action_controller.per_form_csrf_tokens = true
86
90
  action_controller.forgery_protection_origin_check = true
91
+ action_controller.urlsafe_csrf_tokens = false
87
92
  end
88
93
 
89
94
  ActiveSupport.to_time_preserves_timezone = true
@@ -116,7 +121,7 @@ module Rails
116
121
 
117
122
  if respond_to?(:active_support)
118
123
  active_support.use_authenticated_message_encryption = true
119
- active_support.hash_digest_class = ::Digest::SHA1
124
+ active_support.hash_digest_class = OpenSSL::Digest::SHA1
120
125
  end
121
126
 
122
127
  if respond_to?(:action_controller)
@@ -129,8 +134,6 @@ module Rails
129
134
  when "6.0"
130
135
  load_defaults "5.2"
131
136
 
132
- self.autoloader = :zeitwerk if RUBY_ENGINE == "ruby"
133
-
134
137
  if respond_to?(:action_view)
135
138
  action_view.default_enforce_utf8 = false
136
139
  end
@@ -156,20 +159,13 @@ module Rails
156
159
  when "6.1"
157
160
  load_defaults "6.0"
158
161
 
159
- self.autoloader = :zeitwerk if %w[ruby truffleruby].include?(RUBY_ENGINE)
160
-
161
162
  if respond_to?(:active_record)
162
163
  active_record.has_many_inversing = true
163
164
  active_record.legacy_connection_handling = false
164
165
  end
165
166
 
166
- if respond_to?(:active_storage)
167
- active_storage.track_variants = true
168
- end
169
-
170
167
  if respond_to?(:active_job)
171
168
  active_job.retry_jitter = 0.15
172
- active_job.skip_after_callbacks_if_terminated = true
173
169
  end
174
170
 
175
171
  if respond_to?(:action_dispatch)
@@ -178,14 +174,17 @@ module Rails
178
174
  end
179
175
 
180
176
  if respond_to?(:action_controller)
181
- action_controller.urlsafe_csrf_tokens = true
177
+ action_controller.delete(:urlsafe_csrf_tokens)
182
178
  end
183
179
 
184
180
  if respond_to?(:action_view)
185
181
  action_view.form_with_generates_remote_forms = false
182
+ action_view.preload_links_header = true
186
183
  end
187
184
 
188
185
  if respond_to?(:active_storage)
186
+ active_storage.track_variants = true
187
+
189
188
  active_storage.queues.analysis = nil
190
189
  active_storage.queues.purge = nil
191
190
  end
@@ -200,6 +199,62 @@ module Rails
200
199
  end
201
200
 
202
201
  ActiveSupport.utc_to_local_returns_utc_offset_times = true
202
+ when "7.0"
203
+ load_defaults "6.1"
204
+
205
+ if respond_to?(:action_dispatch)
206
+ action_dispatch.default_headers = {
207
+ "X-Frame-Options" => "SAMEORIGIN",
208
+ "X-XSS-Protection" => "0",
209
+ "X-Content-Type-Options" => "nosniff",
210
+ "X-Download-Options" => "noopen",
211
+ "X-Permitted-Cross-Domain-Policies" => "none",
212
+ "Referrer-Policy" => "strict-origin-when-cross-origin"
213
+ }
214
+ action_dispatch.return_only_request_media_type_on_content_type = false
215
+ action_dispatch.cookies_serializer = :json
216
+ end
217
+
218
+ if respond_to?(:action_view)
219
+ action_view.button_to_generates_button_tag = true
220
+ action_view.apply_stylesheet_media_default = false
221
+ end
222
+
223
+ if respond_to?(:active_support)
224
+ active_support.hash_digest_class = OpenSSL::Digest::SHA256
225
+ active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
226
+ active_support.remove_deprecated_time_with_zone_name = true
227
+ active_support.cache_format_version = 7.0
228
+ active_support.use_rfc4122_namespaced_uuids = true
229
+ active_support.executor_around_test_case = true
230
+ active_support.isolation_level = :thread
231
+ active_support.disable_to_s_conversion = true
232
+ end
233
+
234
+ if respond_to?(:action_mailer)
235
+ action_mailer.smtp_timeout = 5
236
+ end
237
+
238
+ if respond_to?(:active_storage)
239
+ active_storage.video_preview_arguments =
240
+ "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1'" \
241
+ " -frames:v 1 -f image2"
242
+
243
+ active_storage.variant_processor = :vips
244
+ active_storage.multiple_file_field_include_hidden = true
245
+ end
246
+
247
+ if respond_to?(:active_record)
248
+ active_record.verify_foreign_keys_for_fixtures = true
249
+ active_record.partial_inserts = false
250
+ active_record.automatic_scope_inversing = true
251
+ end
252
+
253
+ if respond_to?(:action_controller)
254
+ action_controller.raise_on_open_redirects = true
255
+
256
+ action_controller.wrap_parameters_by_default = true
257
+ end
203
258
  else
204
259
  raise "Unknown version #{target_version.to_s.inspect}"
205
260
  end
@@ -255,10 +310,13 @@ module Rails
255
310
  if path = paths["config/database"].existent.first
256
311
  require "rails/application/dummy_erb_compiler"
257
312
 
258
- yaml = Pathname.new(path)
259
- erb = DummyERB.new(yaml.read)
313
+ yaml = DummyERB.new(Pathname.new(path).read).result
260
314
 
261
- YAML.load(erb.result) || {}
315
+ if YAML.respond_to?(:unsafe_load)
316
+ YAML.unsafe_load(yaml) || {}
317
+ else
318
+ YAML.load(yaml) || {}
319
+ end
262
320
  else
263
321
  {}
264
322
  end
@@ -327,7 +385,7 @@ module Rails
327
385
  end
328
386
  end
329
387
 
330
- def session_store? #:nodoc:
388
+ def session_store? # :nodoc:
331
389
  @session_store
332
390
  end
333
391
 
@@ -351,18 +409,6 @@ module Rails
351
409
  end
352
410
  end
353
411
 
354
- def autoloader=(autoloader)
355
- case autoloader
356
- when :classic
357
- @autoloader = autoloader
358
- when :zeitwerk
359
- require "zeitwerk"
360
- @autoloader = autoloader
361
- else
362
- raise ArgumentError, "config.autoloader may be :classic or :zeitwerk, got #{autoloader.inspect} instead"
363
- end
364
- end
365
-
366
412
  def default_log_file
367
413
  path = paths["log"].first
368
414
  unless File.exist? File.dirname path
@@ -375,7 +421,7 @@ module Rails
375
421
  f
376
422
  end
377
423
 
378
- class Custom #:nodoc:
424
+ class Custom # :nodoc:
379
425
  def initialize
380
426
  @configurations = Hash.new
381
427
  end
@@ -13,7 +13,7 @@ module Rails
13
13
 
14
14
  def build_stack
15
15
  ActionDispatch::MiddlewareStack.new do |middleware|
16
- middleware.use ::ActionDispatch::HostAuthorization, config.hosts, config.action_dispatch.hosts_response_app, **config.host_authorization
16
+ middleware.use ::ActionDispatch::HostAuthorization, config.hosts, **config.host_authorization
17
17
 
18
18
  if config.force_ssl
19
19
  middleware.use ::ActionDispatch::SSL, **config.ssl_options,
@@ -42,6 +42,7 @@ module Rails
42
42
 
43
43
  middleware.use ::ActionDispatch::Executor, app.executor
44
44
 
45
+ middleware.use ::ActionDispatch::ServerTiming if config.server_timing
45
46
  middleware.use ::Rack::Runtime
46
47
  middleware.use ::Rack::MethodOverride unless config.api_only
47
48
  middleware.use ::ActionDispatch::RequestId, header: config.action_dispatch.request_id_header
@@ -50,7 +51,10 @@ module Rails
50
51
  middleware.use ::Rails::Rack::Logger, config.log_tags
51
52
  middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
52
53
  middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format
53
- middleware.use ::ActionDispatch::ActionableExceptions
54
+
55
+ if config.consider_all_requests_local
56
+ middleware.use ::ActionDispatch::ActionableExceptions
57
+ end
54
58
 
55
59
  unless config.cache_classes
56
60
  middleware.use ::ActionDispatch::Reloader, app.reloader
@@ -64,10 +68,10 @@ module Rails
64
68
  config.session_options[:secure] = true
65
69
  end
66
70
  middleware.use config.session_store, config.session_options
67
- middleware.use ::ActionDispatch::Flash
68
71
  end
69
72
 
70
73
  unless config.api_only
74
+ middleware.use ::ActionDispatch::Flash
71
75
  middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
72
76
  middleware.use ::ActionDispatch::PermissionsPolicy::Middleware
73
77
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "zeitwerk"
3
4
  require "active_support/core_ext/string/inflections"
4
5
  require "active_support/core_ext/array/conversions"
6
+ require "active_support/descendants_tracker"
7
+ require "active_support/dependencies"
5
8
 
6
9
  module Rails
7
10
  class Application
@@ -12,88 +15,34 @@ module Rails
12
15
  config.generators.templates.unshift(*paths["lib/templates"].existent)
13
16
  end
14
17
 
15
- initializer :ensure_autoload_once_paths_as_subset do
16
- extra = ActiveSupport::Dependencies.autoload_once_paths -
17
- ActiveSupport::Dependencies.autoload_paths
18
+ initializer :setup_main_autoloader do
19
+ autoloader = Rails.autoloaders.main
18
20
 
19
- unless extra.empty?
20
- abort <<-end_error
21
- autoload_once_paths must be a subset of the autoload_paths.
22
- Extra items in autoload_once_paths: #{extra * ','}
23
- end_error
24
- end
25
- end
21
+ ActiveSupport::Dependencies.autoload_paths.freeze
22
+ ActiveSupport::Dependencies.autoload_paths.uniq.each do |path|
23
+ # Zeitwerk only accepts existing directories in `push_dir`.
24
+ next unless File.directory?(path)
26
25
 
27
- # This will become an error if/when we remove classic mode. The plan is
28
- # autoloaders won't be configured up to this point in the finisher, so
29
- # constants just won't be found, raising regular NameError exceptions.
30
- initializer :warn_if_autoloaded, before: :let_zeitwerk_take_over do
31
- next if config.cache_classes
32
- next if ActiveSupport::Dependencies.autoloaded_constants.empty?
33
-
34
- autoloaded = ActiveSupport::Dependencies.autoloaded_constants
35
- constants = "constant".pluralize(autoloaded.size)
36
- enum = autoloaded.to_sentence
37
- have = autoloaded.size == 1 ? "has" : "have"
38
- these = autoloaded.size == 1 ? "This" : "These"
39
- example = autoloaded.first
40
- example_klass = example.constantize.class
41
-
42
- if config.autoloader == :zeitwerk
43
- ActiveSupport::DescendantsTracker.clear
44
- ActiveSupport::Dependencies.clear
45
-
46
- unload_message = "#{these} autoloaded #{constants} #{have} been unloaded."
47
- else
48
- unload_message = "`config.autoloader` is set to `#{config.autoloader}`. #{these} autoloaded #{constants} would have been unloaded if `config.autoloader` had been set to `:zeitwerk`."
26
+ autoloader.push_dir(path)
27
+ autoloader.do_not_eager_load(path) unless ActiveSupport::Dependencies.eager_load?(path)
49
28
  end
50
29
 
51
- ActiveSupport::Deprecation.warn(<<~WARNING)
52
- Initialization autoloaded the #{constants} #{enum}.
53
-
54
- Being able to do this is deprecated. Autoloading during initialization is going
55
- to be an error condition in future versions of Rails.
56
-
57
- Reloading does not reboot the application, and therefore code executed during
58
- initialization does not run again. So, if you reload #{example}, for example,
59
- the expected changes won't be reflected in that stale #{example_klass} object.
60
-
61
- #{unload_message}
62
-
63
- In order to autoload safely at boot time, please wrap your code in a reloader
64
- callback this way:
30
+ unless config.cache_classes
31
+ autoloader.enable_reloading
32
+ ActiveSupport::Dependencies.autoloader = autoloader
65
33
 
66
- Rails.application.reloader.to_prepare do
67
- # Autoload classes and modules needed at boot time here.
68
- end
69
-
70
- That block runs when the application boots, and every time there is a reload.
71
- For historical reasons, it may run twice, so it has to be idempotent.
72
-
73
- Check the "Autoloading and Reloading Constants" guide to learn more about how
74
- Rails autoloads and reloads.
75
- WARNING
76
- end
77
-
78
- initializer :let_zeitwerk_take_over do
79
- if config.autoloader == :zeitwerk
80
- require "active_support/dependencies/zeitwerk_integration"
81
- ActiveSupport::Dependencies::ZeitwerkIntegration.take_over(enable_reloading: !config.cache_classes)
82
- end
83
- end
84
-
85
- initializer :add_builtin_route do |app|
86
- if Rails.env.development?
87
- app.routes.prepend do
88
- get "/rails/info/properties" => "rails/info#properties", internal: true
89
- get "/rails/info/routes" => "rails/info#routes", internal: true
90
- get "/rails/info" => "rails/info#index", internal: true
34
+ autoloader.on_load do |_cpath, value, _abspath|
35
+ if value.is_a?(Class) && value.singleton_class < ActiveSupport::DescendantsTracker
36
+ ActiveSupport::Dependencies._autoloaded_tracked_classes << value
37
+ end
91
38
  end
92
39
 
93
- app.routes.append do
94
- get "/" => "rails/welcome#index", internal: true
40
+ autoloader.on_unload do |_cpath, value, _abspath|
41
+ value.before_remove_const if value.respond_to?(:before_remove_const)
95
42
  end
96
43
  end
44
+
45
+ autoloader.setup
97
46
  end
98
47
 
99
48
  # Setup default session store if not already set in config/application.rb
@@ -127,10 +76,7 @@ module Rails
127
76
  initializer :eager_load! do
128
77
  if config.eager_load
129
78
  ActiveSupport.run_load_hooks(:before_eager_load, self)
130
- # Checks defined?(Zeitwerk) instead of zeitwerk_enabled? because we
131
- # want to eager load any dependency managed by Zeitwerk regardless of
132
- # the autoloading mode of the application.
133
- Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk)
79
+ Zeitwerk::Loader.eager_load_all
134
80
  config.eager_load_namespaces.each(&:eager_load!)
135
81
  end
136
82
  end
@@ -187,6 +133,22 @@ module Rails
187
133
  end
188
134
  end
189
135
 
136
+ initializer :add_internal_routes do |app|
137
+ if Rails.env.development?
138
+ app.routes.prepend do
139
+ get "/rails/info/properties" => "rails/info#properties", internal: true
140
+ get "/rails/info/routes" => "rails/info#routes", internal: true
141
+ get "/rails/info" => "rails/info#index", internal: true
142
+ end
143
+
144
+ routes_reloader.run_after_load_paths = -> do
145
+ app.routes.append do
146
+ get "/" => "rails/welcome#index", internal: true
147
+ end
148
+ end
149
+ end
150
+ end
151
+
190
152
  # Set routes reload after the finisher hook to ensure routes added in
191
153
  # the hook are taken into account.
192
154
  initializer :set_routes_reloader_hook do |app|
@@ -213,7 +175,8 @@ module Rails
213
175
  # added in the hook are taken into account.
214
176
  initializer :set_clear_dependencies_hook, group: :all do |app|
215
177
  callback = lambda do
216
- ActiveSupport::DescendantsTracker.clear
178
+ # Order matters.
179
+ ActiveSupport::DescendantsTracker.clear(ActiveSupport::Dependencies._autoloaded_tracked_classes)
217
180
  ActiveSupport::Dependencies.clear
218
181
  end
219
182
 
@@ -229,6 +192,7 @@ module Rails
229
192
 
230
193
  if config.cache_classes
231
194
  # No reloader
195
+ ActiveSupport::DescendantsTracker.disable_clear!
232
196
  elsif config.reload_classes_only_on_change
233
197
  reloader = config.file_watcher.new(*watchable_args, &callback)
234
198
  reloaders << reloader
@@ -251,13 +215,6 @@ module Rails
251
215
  end
252
216
  end
253
217
  end
254
-
255
- # Disable dependency loading during request cycle
256
- initializer :disable_dependency_loading do
257
- if config.eager_load && config.cache_classes && !config.enable_dependency_loading
258
- ActiveSupport::Dependencies.unhook!
259
- end
260
- end
261
218
  end
262
219
  end
263
220
  end
@@ -5,8 +5,11 @@ require "active_support/core_ext/module/delegation"
5
5
  module Rails
6
6
  class Application
7
7
  class RoutesReloader
8
+ include ActiveSupport::Callbacks
9
+
8
10
  attr_reader :route_sets, :paths, :external_routes
9
11
  attr_accessor :eager_load
12
+ attr_writer :run_after_load_paths # :nodoc:
10
13
  delegate :execute_if_updated, :execute, :updated?, to: :updater
11
14
 
12
15
  def initialize
@@ -45,6 +48,11 @@ module Rails
45
48
 
46
49
  def load_paths
47
50
  paths.each { |path| load(path) }
51
+ run_after_load_paths.call
52
+ end
53
+
54
+ def run_after_load_paths
55
+ @run_after_load_paths ||= -> { }
48
56
  end
49
57
 
50
58
  def finalize!