activesupport 8.0.3 → 8.1.1

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +315 -159
  3. data/lib/active_support/backtrace_cleaner.rb +71 -0
  4. data/lib/active_support/cache/mem_cache_store.rb +13 -13
  5. data/lib/active_support/cache/redis_cache_store.rb +36 -30
  6. data/lib/active_support/cache/strategy/local_cache.rb +16 -7
  7. data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
  8. data/lib/active_support/cache.rb +69 -6
  9. data/lib/active_support/callbacks.rb +20 -8
  10. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
  11. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  12. data/lib/active_support/configurable.rb +34 -0
  13. data/lib/active_support/continuous_integration.rb +145 -0
  14. data/lib/active_support/core_ext/array.rb +7 -7
  15. data/lib/active_support/core_ext/benchmark.rb +4 -12
  16. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  17. data/lib/active_support/core_ext/class/attribute.rb +8 -6
  18. data/lib/active_support/core_ext/class.rb +2 -2
  19. data/lib/active_support/core_ext/date.rb +5 -5
  20. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
  21. data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
  22. data/lib/active_support/core_ext/date_time.rb +5 -5
  23. data/lib/active_support/core_ext/digest.rb +1 -1
  24. data/lib/active_support/core_ext/enumerable.rb +2 -2
  25. data/lib/active_support/core_ext/erb/util.rb +3 -3
  26. data/lib/active_support/core_ext/file.rb +1 -1
  27. data/lib/active_support/core_ext/hash.rb +8 -8
  28. data/lib/active_support/core_ext/integer.rb +3 -3
  29. data/lib/active_support/core_ext/kernel.rb +3 -3
  30. data/lib/active_support/core_ext/module.rb +11 -11
  31. data/lib/active_support/core_ext/numeric.rb +3 -3
  32. data/lib/active_support/core_ext/object/json.rb +8 -1
  33. data/lib/active_support/core_ext/object/to_query.rb +5 -0
  34. data/lib/active_support/core_ext/object.rb +13 -13
  35. data/lib/active_support/core_ext/pathname.rb +2 -2
  36. data/lib/active_support/core_ext/range.rb +4 -5
  37. data/lib/active_support/core_ext/string/multibyte.rb +10 -1
  38. data/lib/active_support/core_ext/string/output_safety.rb +19 -12
  39. data/lib/active_support/core_ext/string.rb +13 -13
  40. data/lib/active_support/core_ext/symbol.rb +1 -1
  41. data/lib/active_support/core_ext/time/calculations.rb +0 -7
  42. data/lib/active_support/core_ext/time/compatibility.rb +2 -27
  43. data/lib/active_support/core_ext/time.rb +5 -5
  44. data/lib/active_support/core_ext.rb +1 -1
  45. data/lib/active_support/current_attributes/test_helper.rb +2 -2
  46. data/lib/active_support/current_attributes.rb +13 -10
  47. data/lib/active_support/dependencies/interlock.rb +11 -5
  48. data/lib/active_support/dependencies.rb +6 -1
  49. data/lib/active_support/deprecation/reporting.rb +4 -2
  50. data/lib/active_support/deprecation.rb +1 -1
  51. data/lib/active_support/editor.rb +70 -0
  52. data/lib/active_support/error_reporter.rb +50 -6
  53. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  54. data/lib/active_support/event_reporter.rb +592 -0
  55. data/lib/active_support/evented_file_update_checker.rb +5 -1
  56. data/lib/active_support/execution_context.rb +64 -7
  57. data/lib/active_support/file_update_checker.rb +7 -5
  58. data/lib/active_support/gem_version.rb +2 -2
  59. data/lib/active_support/gzip.rb +1 -0
  60. data/lib/active_support/hash_with_indifferent_access.rb +27 -7
  61. data/lib/active_support/i18n_railtie.rb +2 -2
  62. data/lib/active_support/inflector/inflections.rb +31 -15
  63. data/lib/active_support/inflector/transliterate.rb +6 -8
  64. data/lib/active_support/isolated_execution_state.rb +12 -15
  65. data/lib/active_support/json/decoding.rb +2 -2
  66. data/lib/active_support/json/encoding.rb +135 -17
  67. data/lib/active_support/log_subscriber.rb +2 -6
  68. data/lib/active_support/message_encryptors.rb +52 -0
  69. data/lib/active_support/message_pack/extensions.rb +5 -0
  70. data/lib/active_support/message_verifiers.rb +52 -0
  71. data/lib/active_support/messages/rotation_coordinator.rb +9 -0
  72. data/lib/active_support/messages/rotator.rb +5 -0
  73. data/lib/active_support/multibyte/chars.rb +8 -1
  74. data/lib/active_support/multibyte.rb +4 -0
  75. data/lib/active_support/notifications/fanout.rb +64 -42
  76. data/lib/active_support/notifications/instrumenter.rb +1 -1
  77. data/lib/active_support/railtie.rb +32 -15
  78. data/lib/active_support/structured_event_subscriber.rb +99 -0
  79. data/lib/active_support/subscriber.rb +0 -5
  80. data/lib/active_support/syntax_error_proxy.rb +3 -0
  81. data/lib/active_support/test_case.rb +61 -6
  82. data/lib/active_support/testing/assertions.rb +34 -6
  83. data/lib/active_support/testing/error_reporter_assertions.rb +18 -1
  84. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  85. data/lib/active_support/testing/notification_assertions.rb +92 -0
  86. data/lib/active_support/testing/parallelization/server.rb +15 -2
  87. data/lib/active_support/testing/parallelization/worker.rb +4 -2
  88. data/lib/active_support/testing/parallelization.rb +25 -1
  89. data/lib/active_support/testing/tests_without_assertions.rb +1 -1
  90. data/lib/active_support/testing/time_helpers.rb +7 -3
  91. data/lib/active_support/time_with_zone.rb +22 -22
  92. data/lib/active_support/values/time_zone.rb +8 -1
  93. data/lib/active_support/xml_mini.rb +3 -2
  94. data/lib/active_support.rb +20 -15
  95. metadata +24 -17
  96. data/lib/active_support/core_ext/range/each.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2cdf9736ba5b94841913f95e5e83f01cc82becad9006ed2d75e18f1cc117c43
4
- data.tar.gz: 7f8f545780e7ecfece1bdd6af006e504d91e89ad019a1020cd43014a296e7def
3
+ metadata.gz: b039f92d3ea92da9f26a0976ed2a520582423f6a4a76fc3ff876b01a752ea95c
4
+ data.tar.gz: bed24bdb19b85bc7d5aaa866a91c92f7661e54d3276a7dd7f1f99724d35bee79
5
5
  SHA512:
6
- metadata.gz: b23ff4bae6aae8f2e154b478c8f36825d0179152a0591591c240ea2b8d6104dcad0b70598a9b42888ab41448a06bc6b69c4ca537c1e5edb386fa81408f25acde
7
- data.tar.gz: 84fa236c5c86feff0ae2283888ca7266c5f5d9090474b099c2b9142c082e107062bea571d8197f0138a022d7db7fe08e02f3544ade6cd611de68c35b26b90e75
6
+ metadata.gz: 1988996636e1e6e8b8c7f54ec0bc0fc0be22eae66dc3048adc8bf00edcb1fc812154dc770f768d3ebffbb5d1edd9191d64b59dac81264c0e1ca3d11e9578cf60
7
+ data.tar.gz: 2d785dd9295cfef86a9e390ed59f7ea1094f94410079e00a1d6cfb2fcc71bd2ec205cd1256d3ebc688c3cbfafabc5eff95715213dc09626993440816e6c33c7f
data/CHANGELOG.md CHANGED
@@ -1,309 +1,465 @@
1
- ## Rails 8.0.3 (September 22, 2025) ##
1
+ ## Rails 8.1.1 (October 28, 2025) ##
2
2
 
3
- * `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unnecessary reloads with time travel test helpers
3
+ * No changes.
4
4
 
5
- *Jan Grodowski*
6
5
 
7
- * Fix `ActiveSupport::BroadcastLogger` from executing a block argument for each logger (tagged, info, etc.).
6
+ ## Rails 8.1.0 (October 22, 2025) ##
8
7
 
9
- *Jared Armstrong*
8
+ * Remove deprecated passing a Time object to `Time#since`.
10
9
 
11
- * Make `ActiveSupport::Logger` `#freeze`-friendly.
10
+ *Rafael Mendonça França*
12
11
 
13
- *Joshua Young*
12
+ * Remove deprecated `Benchmark.ms` method. It is now defined in the `benchmark` gem.
14
13
 
15
- * Fix `ActiveSupport::HashWithIndifferentAccess#transform_keys!` removing defaults.
14
+ *Rafael Mendonça França*
16
15
 
17
- *Hartley McGuire*
16
+ * Remove deprecated addition for `Time` instances with `ActiveSupport::TimeWithZone`.
18
17
 
19
- * Fix `ActiveSupport::HashWithIndifferentAccess#tranform_keys!` to handle collisions.
18
+ *Rafael Mendonça França*
20
19
 
21
- If the transformation would result in a key equal to another not yet transformed one,
22
- it would result in keys being lost.
20
+ * Remove deprecated support for `to_time` to preserve the system local time. It will now always preserve the receiver
21
+ timezone.
23
22
 
24
- Before:
23
+ *Rafael Mendonça França*
25
24
 
26
- ```ruby
27
- >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
28
- => {"c" => 1}
29
- ```
25
+ * Deprecate `config.active_support.to_time_preserves_timezone`.
30
26
 
31
- After:
27
+ *Rafael Mendonça França*
32
28
 
33
- ```ruby
34
- >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
35
- => {"c" => 1, "d" => 2}
36
- ```
29
+ * Standardize event name formatting in `assert_event_reported` error messages.
37
30
 
38
- *Jason T Johnson*, *Jean Boussier*
31
+ The event name in failure messages now uses `.inspect` (e.g., `name: "user.created"`)
32
+ to match `assert_events_reported` and provide type clarity between strings and symbols.
33
+ This only affects tests that assert on the failure message format itself.
39
34
 
40
- * Fix `ActiveSupport::Cache::MemCacheStore#read_multi` to handle network errors.
35
+ *George Ma*
41
36
 
42
- This method specifically wasn't handling network errors like other codepaths.
37
+ * Fix `Enumerable#sole` to return the full tuple instead of just the first element of the tuple.
43
38
 
44
- *Alessandro Dal Grande*
39
+ *Olivier Bellone*
45
40
 
46
- * Fix configuring `RedisCacheStore` with `raw: true`.
41
+ * Fix parallel tests hanging when worker processes die abruptly.
47
42
 
48
- *fatkodima*
43
+ Previously, if a worker process was killed (e.g., OOM killed, `kill -9`) during parallel
44
+ test execution, the test suite would hang forever waiting for the dead worker.
49
45
 
50
- * Fix `Enumerable#sole` for infinite collections.
46
+ *Joshua Young*
51
47
 
52
- *fatkodima*
48
+ * Add `config.active_support.escape_js_separators_in_json`.
53
49
 
50
+ Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.
54
51
 
55
- ## Rails 8.0.2.1 (August 13, 2025) ##
52
+ Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
53
+ As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
56
54
 
57
- * No changes.
55
+ *Étienne Barrié*, *Jean Boussier*
58
56
 
57
+ * Fix `NameError` when `class_attribute` is defined on instance singleton classes.
59
58
 
60
- ## Rails 8.0.2 (March 12, 2025) ##
59
+ Previously, calling `class_attribute` on an instance's singleton class would raise
60
+ a `NameError` when accessing the attribute through the instance.
61
61
 
62
- * Fix setting `to_time_preserves_timezone` from `new_framework_defaults_8_0.rb`.
62
+ ```ruby
63
+ object = MyClass.new
64
+ object.singleton_class.class_attribute :foo, default: "bar"
65
+ object.foo # previously raised NameError, now returns "bar"
66
+ ```
63
67
 
64
- *fatkodima*
68
+ *Joshua Young*
65
69
 
66
- * Fix Active Support Cache `fetch_multi` when local store is active.
70
+ * Introduce `ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting`
71
+ to enable event reporter debug mode in tests.
67
72
 
68
- `fetch_multi` now properly yield to the provided block for missing entries
69
- that have been recorded as such in the local store.
73
+ The previous way to enable debug mode is by using `#with_debug` on the
74
+ event reporter itself, which is too verbose. This new helper will help
75
+ clear up any confusion on how to test debug events.
70
76
 
71
- *Jean Boussier*
77
+ *Gannon McGibbon*
72
78
 
73
- * Fix execution wrapping to report all exceptions, including `Exception`.
79
+ * Add `ActiveSupport::StructuredEventSubscriber` for consuming notifications and
80
+ emitting structured event logs. Events may be emitted with the `#emit_event`
81
+ or `#emit_debug_event` methods.
74
82
 
75
- If a more serious error like `SystemStackError` or `NoMemoryError` happens,
76
- the error reporter should be able to report these kinds of exceptions.
83
+ ```ruby
84
+ class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber
85
+ def notification(event)
86
+ emit_event("my.notification", data: 1)
87
+ end
88
+ end
89
+ ```
77
90
 
78
- *Gannon McGibbon*
91
+ *Adrianna Chang*
79
92
 
80
- * Fix `RedisCacheStore` and `MemCacheStore` to also handle connection pool related errors.
93
+ * `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unecessary reloads with time travel test helpers
81
94
 
82
- These errors are rescued and reported to `Rails.error`.
95
+ *Jan Grodowski*
83
96
 
84
- *Jean Boussier*
97
+ * Add `ActiveSupport::Cache::Store#namespace=` and `#namespace`.
85
98
 
86
- * Fix `ActiveSupport::Cache#read_multi` to respect version expiry when using local cache.
99
+ Can be used as an alternative to `Store#clear` in some situations such as parallel
100
+ testing.
87
101
 
88
- *zzak*
102
+ *Nick Schwaderer*
103
+
104
+ * Create `parallel_worker_id` helper for running parallel tests. This allows users to
105
+ know which worker they are currently running in.
106
+
107
+ *Nick Schwaderer*
108
+
109
+ * Make the cache of `ActiveSupport::Cache::Strategy::LocalCache::Middleware` updatable.
110
+
111
+ If the cache client at `Rails.cache` of a booted application changes, the corresponding
112
+ mounted middleware needs to update in order for request-local caches to be setup properly.
113
+ Otherwise, redundant cache operations will erroneously hit the datastore.
114
+
115
+ *Gannon McGibbon*
89
116
 
90
- * Fix `ActiveSupport::MessageVerifier` and `ActiveSupport::MessageEncryptor` configuration of `on_rotation` callback.
117
+ * Add `assert_events_reported` test helper for `ActiveSupport::EventReporter`.
118
+
119
+ This new assertion allows testing multiple events in a single block, regardless of order:
91
120
 
92
121
  ```ruby
93
- verifier.rotate(old_secret).on_rotation { ... }
122
+ assert_events_reported([
123
+ { name: "user.created", payload: { id: 123 } },
124
+ { name: "email.sent", payload: { to: "user@example.com" } }
125
+ ]) do
126
+ create_user_and_send_welcome_email
127
+ end
94
128
  ```
95
129
 
96
- Now both work as documented.
130
+ *George Ma*
97
131
 
98
- *Jean Boussier*
132
+ * Add `ActiveSupport::TimeZone#standard_name` method.
133
+
134
+ ``` ruby
135
+ zone = ActiveSupport::TimeZone['Hawaii']
136
+ # Old way
137
+ ActiveSupport::TimeZone::MAPPING[zone.name]
138
+ # New way
139
+ zone.standard_name # => 'Pacific/Honolulu'
140
+ ```
141
+
142
+ *Bogdan Gusiev*
143
+
144
+ * Add Structured Event Reporter, accessible via `Rails.event`.
145
+
146
+ The Event Reporter provides a unified interface for producing structured events in Rails
147
+ applications:
99
148
 
100
- * Fix `ActiveSupport::MessageVerifier` to always be able to verify both URL-safe and URL-unsafe payloads.
149
+ ```ruby
150
+ Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
151
+ ```
101
152
 
102
- This is to allow transitioning seemlessly from either configuration without immediately invalidating
103
- all previously generated signed messages.
153
+ It supports adding tags to events:
154
+
155
+ ```ruby
156
+ Rails.event.tagged("graphql") do
157
+ # Event includes tags: { graphql: true }
158
+ Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
159
+ end
160
+ ```
104
161
 
105
- *Jean Boussier*, *Florent Beaurain*, *Ali Sepehri*
162
+ As well as context:
163
+ ```ruby
164
+ # All events will contain context: {request_id: "abc123", shop_id: 456}
165
+ Rails.event.set_context(request_id: "abc123", shop_id: 456)
166
+ ```
106
167
 
107
- * Fix `cache.fetch` to honor the provided expiry when `:race_condition_ttl` is used.
168
+ Events are emitted to subscribers. Applications register subscribers to
169
+ control how events are serialized and emitted. Subscribers must implement
170
+ an `#emit` method, which receives the event hash:
108
171
 
109
172
  ```ruby
110
- cache.fetch("key", expires_in: 1.hour, race_condition_ttl: 5.second) do
111
- "something"
173
+ class LogSubscriber
174
+ def emit(event)
175
+ payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
176
+ source_location = event[:source_location]
177
+ log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
178
+ Rails.logger.info(log)
179
+ end
112
180
  end
113
181
  ```
114
182
 
115
- In the above example, the final cache entry would have a 10 seconds TTL instead
116
- of the requested 1 hour.
183
+ *Adrianna Chang*
117
184
 
118
- *Dhia*
185
+ * Make `ActiveSupport::Logger` `#freeze`-friendly.
119
186
 
120
- * Better handle procs with splat arguments in `set_callback`.
187
+ *Joshua Young*
121
188
 
122
- *Radamés Roriz*
189
+ * Make `ActiveSupport::Gzip.compress` deterministic based on input.
123
190
 
124
- * Fix `String#mb_chars` to not mutate the receiver.
191
+ `ActiveSupport::Gzip.compress` used to include a timestamp in the output,
192
+ causing consecutive calls with the same input data to have different output
193
+ if called during different seconds. It now always sets the timestamp to `0`
194
+ so that the output is identical for any given input.
125
195
 
126
- Previously it would call `force_encoding` on the receiver,
127
- now it dups the receiver first.
196
+ *Rob Brackett*
128
197
 
129
- *Jean Boussier*
198
+ * Given an array of `Thread::Backtrace::Location` objects, the new method
199
+ `ActiveSupport::BacktraceCleaner#clean_locations` returns an array with the
200
+ clean ones:
130
201
 
131
- * Improve `ErrorSubscriber` to also mark error causes as reported.
202
+ ```ruby
203
+ clean_locations = backtrace_cleaner.clean_locations(caller_locations)
204
+ ```
132
205
 
133
- This avoid some cases of errors being reported twice, notably in views because of how
134
- errors are wrapped in `ActionView::Template::Error`.
206
+ Filters and silencers receive strings as usual. However, the `path`
207
+ attributes of the locations in the returned array are the original,
208
+ unfiltered ones, since locations are immutable.
135
209
 
136
- *Jean Boussier*
210
+ *Xavier Noria*
137
211
 
138
- * Fix `Module#module_parent_name` to return the correct name after the module has been named.
212
+ * Improve `CurrentAttributes` and `ExecutionContext` state managment in test cases.
139
213
 
140
- When called on an anonymous module, the return value wouldn't change after the module was given a name
141
- later by being assigned to a constant.
214
+ Previously these two global state would be entirely cleared out whenever calling
215
+ into code that is wrapped by the Rails executor, typically Action Controller or
216
+ Active Job helpers:
142
217
 
143
218
  ```ruby
144
- mod = Module.new
145
- mod.module_parent_name # => "Object"
146
- MyModule::Something = mod
147
- mod.module_parent_name # => "MyModule"
219
+ test "#index works" do
220
+ CurrentUser.id = 42
221
+ get :index
222
+ CurrentUser.id == nil
223
+ end
148
224
  ```
149
225
 
226
+ Now re-entering the executor properly save and restore that state.
227
+
150
228
  *Jean Boussier*
151
229
 
230
+ * The new method `ActiveSupport::BacktraceCleaner#first_clean_location`
231
+ returns the first clean location of the caller's call stack, or `nil`.
232
+ Locations are `Thread::Backtrace::Location` objects. Useful when you want to
233
+ report the application-level location where something happened as an object.
152
234
 
153
- ## Rails 8.0.1 (December 13, 2024) ##
235
+ *Xavier Noria*
154
236
 
155
- * Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceeded by multibyte characters.
237
+ * FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.
156
238
 
157
- *Martin Emde*
239
+ *Ermolaev Andrey*, *zzak*
158
240
 
159
- * Restore the ability to decorate methods generated by `class_attribute`.
241
+ * The new method `ActiveSupport::BacktraceCleaner#first_clean_frame` returns
242
+ the first clean frame of the caller's backtrace, or `nil`. Useful when you
243
+ want to report the application-level frame where something happened as a
244
+ string.
160
245
 
161
- It always has been complicated to use Module#prepend or an alias method chain
162
- to decorate methods defined by `class_attribute`, but became even harder in 8.0.
246
+ *Xavier Noria*
163
247
 
164
- This capability is now supported for both reader and writer methods.
248
+ * Always clear `CurrentAttributes` instances.
165
249
 
166
- *Jean Boussier*
250
+ Previously `CurrentAttributes` instance would be reset at the end of requests.
251
+ Meaning its attributes would be re-initialized.
167
252
 
253
+ This is problematic because it assume these objects don't hold any state
254
+ other than their declared attribute, which isn't always the case, and
255
+ can lead to state leak across request.
168
256
 
169
- ## Rails 8.0.0.1 (December 10, 2024) ##
257
+ Now `CurrentAttributes` instances are abandoned at the end of a request,
258
+ and a new instance is created at the start of the next request.
170
259
 
171
- * No changes.
260
+ *Jean Boussier*, *Janko Marohnić*
172
261
 
262
+ * Add public API for `before_fork_hook` in parallel testing.
173
263
 
174
- ## Rails 8.0.0 (November 07, 2024) ##
264
+ Introduces a public API for calling the before fork hooks implemented by parallel testing.
175
265
 
176
- * No changes.
266
+ ```ruby
267
+ parallelize_before_fork do
268
+ # perform an action before test processes are forked
269
+ end
270
+ ```
177
271
 
272
+ *Eileen M. Uchitelle*
178
273
 
179
- ## Rails 8.0.0.rc2 (October 30, 2024) ##
274
+ * Implement ability to skip creating parallel testing databases.
180
275
 
181
- * No changes.
276
+ With parallel testing, Rails will create a database per process. If this isn't
277
+ desirable or you would like to implement databases handling on your own, you can
278
+ now turn off this default behavior.
182
279
 
280
+ To skip creating a database per process, you can change it via the
281
+ `parallelize` method:
183
282
 
184
- ## Rails 8.0.0.rc1 (October 19, 2024) ##
283
+ ```ruby
284
+ parallelize(workers: 10, parallelize_databases: false)
285
+ ```
185
286
 
186
- * Remove deprecated support to passing an array of strings to `ActiveSupport::Deprecation#warn`.
287
+ or via the application configuration:
187
288
 
188
- *Rafael Mendonça França*
289
+ ```ruby
290
+ config.active_support.parallelize_databases = false
291
+ ```
189
292
 
190
- * Remove deprecated support to setting `attr_internal_naming_format` with a `@` prefix.
293
+ *Eileen M. Uchitelle*
191
294
 
192
- *Rafael Mendonça França*
295
+ * Allow to configure maximum cache key sizes
193
296
 
194
- * Remove deprecated `ActiveSupport::ProxyObject`.
297
+ When the key exceeds the configured limit (250 bytes by default), it will be truncated and
298
+ the digest of the rest of the key appended to it.
195
299
 
196
- *Rafael Mendonça França*
300
+ Note that previously `ActiveSupport::Cache::RedisCacheStore` allowed up to 1kb cache keys before
301
+ truncation, which is now reduced to 250 bytes.
197
302
 
198
- * Don't execute i18n watcher on boot. It shouldn't catch any file changes initially,
199
- and unnecessarily slows down boot of applications with lots of translations.
303
+ ```ruby
304
+ config.cache_store = :redis_cache_store, { max_key_size: 64 }
305
+ ```
200
306
 
201
- *Gannon McGibbon*, *David Stosik*
307
+ *fatkodima*
202
308
 
203
- * Fix `ActiveSupport::HashWithIndifferentAccess#stringify_keys` to stringify all keys not just symbols.
309
+ * Use `UNLINK` command instead of `DEL` in `ActiveSupport::Cache::RedisCacheStore` for non-blocking deletion.
204
310
 
205
- Previously:
311
+ *Aron Roh*
312
+
313
+ * Add `Cache#read_counter` and `Cache#write_counter`
206
314
 
207
315
  ```ruby
208
- { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
316
+ Rails.cache.write_counter("foo", 1)
317
+ Rails.cache.read_counter("foo") # => 1
318
+ Rails.cache.increment("foo")
319
+ Rails.cache.read_counter("foo") # => 2
209
320
  ```
210
321
 
211
- After this change:
322
+ *Alex Ghiculescu*
323
+
324
+ * Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports
325
+
326
+ Captures all reported errors from within the block that match the given
327
+ error class.
212
328
 
213
329
  ```ruby
214
- { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
330
+ reports = capture_error_reports(IOError) do
331
+ Rails.error.report(IOError.new("Oops"))
332
+ Rails.error.report(IOError.new("Oh no"))
333
+ Rails.error.report(StandardError.new)
334
+ end
335
+
336
+ assert_equal 2, reports.size
337
+ assert_equal "Oops", reports.first.error.message
338
+ assert_equal "Oh no", reports.last.error.message
215
339
  ```
216
340
 
217
- This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
218
- to not backport the fix and to make the change in a major release.
341
+ *Andrew Novoselac*
219
342
 
220
- *Jean Boussier*
343
+ * Introduce ActiveSupport::ErrorReporter#add_middleware
221
344
 
222
- ## Rails 8.0.0.beta1 (September 26, 2024) ##
345
+ When reporting an error, the error context middleware will be called with the reported error
346
+ and base execution context. The stack may mutate the context hash. The mutated context will
347
+ then be passed to error subscribers. Middleware receives the same parameters as `ErrorReporter#report`.
223
348
 
224
- * Include options when instrumenting `ActiveSupport::Cache::Store#delete` and `ActiveSupport::Cache::Store#delete_multi`.
349
+ *Andrew Novoselac*, *Sam Schmidt*
225
350
 
226
- *Adam Renberg Tamm*
351
+ * Change execution wrapping to report all exceptions, including `Exception`.
227
352
 
228
- * Print test names when running `rails test -v` for parallel tests.
353
+ If a more serious error like `SystemStackError` or `NoMemoryError` happens,
354
+ the error reporter should be able to report these kinds of exceptions.
229
355
 
230
- *John Hawthorn*, *Abeid Ahmed*
356
+ *Gannon McGibbon*
231
357
 
232
- * Deprecate `Benchmark.ms` core extension.
358
+ * `ActiveSupport::Testing::Parallelization.before_fork_hook` allows declaration of callbacks that
359
+ are invoked immediately before forking test workers.
233
360
 
234
- The `benchmark` gem will become bundled in Ruby 3.5
361
+ *Mike Dalessio*
235
362
 
236
- *Earlopain*
363
+ * Allow the `#freeze_time` testing helper to accept a date or time argument.
237
364
 
238
- * `ActiveSupport::TimeWithZone#inspect` now uses ISO 8601 style time like `Time#inspect`
365
+ ```ruby
366
+ Time.current # => Sun, 09 Jul 2024 15:34:49 EST -05:00
367
+ freeze_time Time.current + 1.day
368
+ sleep 1
369
+ Time.current # => Mon, 10 Jul 2024 15:34:49 EST -05:00
370
+ ```
239
371
 
240
- *John Hawthorn*
372
+ *Joshua Young*
241
373
 
242
- * `ActiveSupport::ErrorReporter#report` now assigns a backtrace to unraised exceptions.
374
+ * `ActiveSupport::JSON` now accepts options
243
375
 
244
- Previously reporting an un-raised exception would result in an error report without
245
- a backtrace. Now it automatically generates one.
376
+ It is now possible to pass options to `ActiveSupport::JSON`:
377
+ ```ruby
378
+ ActiveSupport::JSON.decode('{"key": "value"}', symbolize_names: true) # => { key: "value" }
379
+ ```
246
380
 
247
- *Jean Boussier*
381
+ *matthaigh27*
248
382
 
249
- * Add `escape_html_entities` option to `ActiveSupport::JSON.encode`.
383
+ * `ActiveSupport::Testing::NotificationAssertions`'s `assert_notification` now matches against payload subsets by default.
250
384
 
251
- This allows for overriding the global configuration found at
252
- `ActiveSupport.escape_html_entities_in_json` for specific calls to `to_json`.
385
+ Previously the following assertion would fail due to excess key vals in the notification payload. Now with payload subset matching, it will pass.
253
386
 
254
- This should be usable from controllers in the following manner:
255
387
  ```ruby
256
- class MyController < ApplicationController
257
- def index
258
- render json: { hello: "world" }, escape_html_entities: false
259
- end
388
+ assert_notification("post.submitted", title: "Cool Post") do
389
+ ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: "Cool Body")
260
390
  end
261
391
  ```
262
392
 
263
- *Nigel Baillie*
393
+ Additionally, you can now persist a matched notification for more customized assertions.
394
+
395
+ ```ruby
396
+ notification = assert_notification("post.submitted", title: "Cool Post") do
397
+ ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: Body.new("Cool Body"))
398
+ end
399
+
400
+ assert_instance_of(Body, notification.payload[:body])
401
+ ```
264
402
 
265
- * Raise when using key which can't respond to `#to_sym` in `EncryptedConfiguration`.
403
+ *Nicholas La Roux*
266
404
 
267
- As is the case when trying to use an Integer or Float as a key, which is unsupported.
405
+ * Deprecate `String#mb_chars` and `ActiveSupport::Multibyte::Chars`.
268
406
 
269
- *zzak*
407
+ These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
408
+ aware. There is no legitimate reasons to need these APIs today.
270
409
 
271
- * Deprecate addition and since between two `Time` and `ActiveSupport::TimeWithZone`.
410
+ *Jean Boussier*
272
411
 
273
- Previously adding time instances together such as `10.days.ago + 10.days.ago` or `10.days.ago.since(10.days.ago)` produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.
412
+ * Deprecate `ActiveSupport::Configurable`
274
413
 
275
- *Nick Schwaderer*
414
+ *Sean Doyle*
276
415
 
277
- * Support rfc2822 format for Time#to_fs & Date#to_fs.
416
+ * `nil.to_query("key")` now returns `key`.
278
417
 
279
- *Akshay Birajdar*
418
+ Previously it would return `key=`, preventing round tripping with `Rack::Utils.parse_nested_query`.
280
419
 
281
- * Optimize load time for `Railtie#initialize_i18n`. Filter `I18n.load_path`s passed to the file watcher to only those
282
- under `Rails.root`. Previously the watcher would grab all available locales, including those in gems
283
- which do not require a watcher because they won't change.
420
+ *Erol Fornoles*
284
421
 
285
- *Nick Schwaderer*
422
+ * Avoid wrapping redis in a `ConnectionPool` when using `ActiveSupport::Cache::RedisCacheStore` if the `:redis`
423
+ option is already a `ConnectionPool`.
286
424
 
287
- * Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
288
- by these values.
425
+ *Joshua Young*
289
426
 
290
- *Igor Depolli*
427
+ * Alter `ERB::Util.tokenize` to return :PLAIN token with full input string when string doesn't contain ERB tags.
291
428
 
292
- * Improve error message when using `assert_difference` or `assert_changes` with a
293
- proc by printing the proc's source code (MRI only).
429
+ *Martin Emde*
294
430
 
295
- *Richard Böhme*, *Jean Boussier*
431
+ * Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceded by multibyte characters.
296
432
 
297
- * Add a new configuration value `:zone` for `ActiveSupport.to_time_preserves_timezone` and rename the previous `true` value to `:offset`. The new default value is `:zone`.
433
+ *Martin Emde*
298
434
 
299
- *Jason Kim*, *John Hawthorn*
435
+ * Add `ActiveSupport::Testing::NotificationAssertions` module to help with testing `ActiveSupport::Notifications`.
300
436
 
301
- * Align instrumentation `payload[:key]` in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys.
437
+ *Nicholas La Roux*, *Yishu See*, *Sean Doyle*
438
+
439
+ * `ActiveSupport::CurrentAttributes#attributes` now will return a new hash object on each call.
440
+
441
+ Previously, the same hash object was returned each time that method was called.
442
+
443
+ *fatkodima*
444
+
445
+ * `ActiveSupport::JSON.encode` supports CIDR notation.
446
+
447
+ Previously:
448
+
449
+ ```ruby
450
+ ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0\""
451
+ ```
452
+
453
+ After this change:
454
+
455
+ ```ruby
456
+ ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0/24\""
457
+ ```
302
458
 
303
- *Frederik Erbs Spang Thomsen*
459
+ *Taketo Takashima*
304
460
 
305
- * Fix `travel_to` to set usec 0 when `with_usec` is `false` and the given argument String or DateTime.
461
+ * Make `ActiveSupport::FileUpdateChecker` faster when checking many file-extensions.
306
462
 
307
- *mopp*
463
+ *Jonathan del Strother*
308
464
 
309
- Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activesupport/CHANGELOG.md) for previous changes.
465
+ Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/activesupport/CHANGELOG.md) for previous changes.