activesupport 7.2.3.1 → 8.1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +584 -234
- data/lib/active_support/backtrace_cleaner.rb +72 -1
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +3 -2
- data/lib/active_support/cache/file_store.rb +13 -2
- data/lib/active_support/cache/mem_cache_store.rb +17 -14
- data/lib/active_support/cache/memory_store.rb +9 -3
- data/lib/active_support/cache/redis_cache_store.rb +51 -34
- data/lib/active_support/cache/strategy/local_cache.rb +17 -8
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
- data/lib/active_support/cache.rb +86 -18
- data/lib/active_support/callbacks.rb +25 -11
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +9 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +34 -0
- data/lib/active_support/configuration_file.rb +15 -6
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/conversions.rb +3 -3
- data/lib/active_support/core_ext/array.rb +7 -7
- data/lib/active_support/core_ext/benchmark.rb +0 -16
- data/lib/active_support/core_ext/big_decimal.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +24 -18
- data/lib/active_support/core_ext/class.rb +2 -2
- data/lib/active_support/core_ext/date/conversions.rb +2 -0
- data/lib/active_support/core_ext/date.rb +5 -5
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
- data/lib/active_support/core_ext/date_time.rb +5 -5
- data/lib/active_support/core_ext/digest.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +8 -3
- data/lib/active_support/core_ext/erb/util.rb +3 -3
- data/lib/active_support/core_ext/file.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -0
- data/lib/active_support/core_ext/hash/except.rb +0 -12
- data/lib/active_support/core_ext/hash.rb +8 -8
- data/lib/active_support/core_ext/integer.rb +3 -3
- data/lib/active_support/core_ext/kernel.rb +3 -3
- data/lib/active_support/core_ext/module/attr_internal.rb +3 -4
- data/lib/active_support/core_ext/module.rb +11 -11
- data/lib/active_support/core_ext/numeric.rb +3 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +24 -11
- data/lib/active_support/core_ext/object/to_query.rb +7 -1
- data/lib/active_support/core_ext/object.rb +13 -13
- data/lib/active_support/core_ext/pathname.rb +2 -2
- data/lib/active_support/core_ext/range/compare_range.rb +2 -14
- data/lib/active_support/core_ext/range/overlap.rb +3 -3
- data/lib/active_support/core_ext/range/sole.rb +2 -0
- data/lib/active_support/core_ext/range.rb +4 -5
- data/lib/active_support/core_ext/string/filters.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/multibyte.rb +10 -1
- data/lib/active_support/core_ext/string/output_safety.rb +27 -13
- data/lib/active_support/core_ext/string.rb +13 -13
- data/lib/active_support/core_ext/symbol.rb +1 -1
- data/lib/active_support/core_ext/thread/backtrace/location.rb +2 -7
- data/lib/active_support/core_ext/time/calculations.rb +11 -2
- data/lib/active_support/core_ext/time/compatibility.rb +2 -27
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/time.rb +5 -5
- data/lib/active_support/current_attributes/test_helper.rb +2 -2
- data/lib/active_support/current_attributes.rb +13 -10
- data/lib/active_support/delegation.rb +25 -44
- data/lib/active_support/dependencies/interlock.rb +11 -5
- data/lib/active_support/dependencies.rb +6 -2
- data/lib/active_support/deprecation/reporting.rb +4 -21
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/duration.rb +20 -16
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +20 -2
- data/lib/active_support/error_reporter.rb +76 -2
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +5 -2
- data/lib/active_support/execution_context.rb +75 -7
- data/lib/active_support/file_update_checker.rb +7 -5
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/gzip.rb +1 -0
- data/lib/active_support/hash_with_indifferent_access.rb +44 -24
- data/lib/active_support/i18n_railtie.rb +19 -11
- data/lib/active_support/inflector/inflections.rb +34 -16
- data/lib/active_support/inflector/methods.rb +6 -22
- data/lib/active_support/inflector/transliterate.rb +18 -10
- data/lib/active_support/isolated_execution_state.rb +17 -17
- data/lib/active_support/json/decoding.rb +9 -3
- data/lib/active_support/json/encoding.rb +149 -19
- data/lib/active_support/log_subscriber.rb +2 -6
- data/lib/active_support/logger_thread_safe_level.rb +6 -3
- data/lib/active_support/message_encryptors.rb +52 -0
- data/lib/active_support/message_pack/extensions.rb +23 -1
- data/lib/active_support/message_verifiers.rb +52 -0
- data/lib/active_support/messages/rotation_coordinator.rb +9 -0
- data/lib/active_support/messages/rotator.rb +5 -0
- data/lib/active_support/messages/serializer_with_fallback.rb +1 -1
- data/lib/active_support/multibyte/chars.rb +8 -1
- data/lib/active_support/multibyte.rb +4 -0
- data/lib/active_support/notifications/fanout.rb +64 -43
- data/lib/active_support/notifications/instrumenter.rb +1 -1
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_converter.rb +4 -1
- data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -4
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -7
- data/lib/active_support/number_helper/rounding_helper.rb +1 -1
- data/lib/active_support/number_helper.rb +22 -0
- data/lib/active_support/ordered_options.rb +2 -2
- data/lib/active_support/railtie.rb +32 -9
- data/lib/active_support/security_utils.rb +4 -5
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +0 -5
- data/lib/active_support/syntax_error_proxy.rb +9 -1
- data/lib/active_support/tagged_logging.rb +5 -0
- data/lib/active_support/test_case.rb +67 -6
- data/lib/active_support/testing/assertions.rb +118 -27
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/error_reporter_assertions.rb +17 -0
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/isolation.rb +0 -2
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/worker.rb +7 -1
- data/lib/active_support/testing/parallelization.rb +17 -0
- data/lib/active_support/testing/tests_without_assertions.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +9 -4
- data/lib/active_support/time_with_zone.rb +36 -23
- data/lib/active_support/values/time_zone.rb +22 -13
- data/lib/active_support/xml_mini.rb +1 -2
- data/lib/active_support.rb +21 -9
- metadata +33 -17
- data/lib/active_support/core_ext/range/each.rb +0 -24
- data/lib/active_support/proxy_object.rb +0 -20
data/CHANGELOG.md
CHANGED
|
@@ -1,453 +1,803 @@
|
|
|
1
|
-
## Rails
|
|
1
|
+
## Rails 8.1.4.1 (November 03, 2026) ##
|
|
2
2
|
|
|
3
|
-
*
|
|
3
|
+
* `ActiveSupport::MessagePack` no longer deserializes an unsafe
|
|
4
|
+
`ActiveSupport::SafeBuffer` as `html_safe`.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
A `SafeBuffer` that was no longer `html_safe?`, for example after an
|
|
7
|
+
in-place `gsub!`, was deserialized as an `html_safe` `SafeBuffer`. It is now
|
|
8
|
+
serialized with an unsafe marker and deserialized as a `String`. Earlier
|
|
9
|
+
versions of Rails cannot read an unsafe buffer serialized this way.
|
|
10
|
+
|
|
11
|
+
[GHSA-2w9f-fxwj-w2qf]
|
|
6
12
|
|
|
7
13
|
*Jean Boussier*
|
|
8
14
|
|
|
9
|
-
*
|
|
15
|
+
* `ActiveSupport::Inflector#safe_constantize` matches the constant name in a
|
|
16
|
+
`LoadError` message as a literal string instead of building a `Regexp`
|
|
17
|
+
from it.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
The name's segments were interpolated unescaped into the pattern, so input
|
|
20
|
+
that reaches `safe_constantize`, such as the channel identifier in an Action
|
|
21
|
+
Cable subscribe command, chose the source passed to the regexp compiler.
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
[GHSA-8474-xrp6-wh69]
|
|
14
24
|
|
|
15
|
-
*
|
|
25
|
+
*Jeremy Daer*
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
## Rails 8.1.4 (September 24, 2026) ##
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
* Fix the debug error page rendering for `SyntaxError`s with multi-line messages.
|
|
20
30
|
|
|
31
|
+
*Marco Roth*
|
|
21
32
|
|
|
22
|
-
|
|
33
|
+
* Make `ActiveSupport::JSON.decode` compatible with the upcoming `json` 3.0 gem.
|
|
23
34
|
|
|
24
|
-
*
|
|
35
|
+
*Earlopain*
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
* Fix `number_to_human_size` crashing for sizes above a terabyte by supporting
|
|
38
|
+
petabyte, exabyte, and zettabyte storage units.
|
|
27
39
|
|
|
28
|
-
*
|
|
40
|
+
*Kenta Ishizaki*
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
* Fix `Range#sole` raising `NoMethodError` when the enumerable core extension
|
|
43
|
+
isn't already loaded.
|
|
32
44
|
|
|
33
|
-
*
|
|
45
|
+
*Kenta Ishizaki*
|
|
34
46
|
|
|
35
|
-
* `ActiveSupport::
|
|
47
|
+
* Fix `ActiveSupport::Cache::FileStore` raising `NameError` for `FileUtils`
|
|
48
|
+
when `fileutils` isn't already loaded.
|
|
36
49
|
|
|
37
|
-
*
|
|
50
|
+
*Kenta Ishizaki*
|
|
38
51
|
|
|
39
|
-
* Fix `
|
|
52
|
+
* Fix `Enumerable#in_order_of` with `filter: true` dropping `nil` elements
|
|
53
|
+
explicitly named in the series.
|
|
40
54
|
|
|
41
|
-
*
|
|
55
|
+
*Kenta Ishizaki*
|
|
42
56
|
|
|
43
|
-
*
|
|
57
|
+
* Keep `HashWithIndifferentAccess#filter` returning a `HashWithIndifferentAccess`
|
|
58
|
+
instead of a plain `Hash`.
|
|
44
59
|
|
|
45
|
-
*
|
|
60
|
+
*Kenta Ishizaki*
|
|
46
61
|
|
|
47
|
-
* Fix `
|
|
62
|
+
* Fix `number_to_human` and `number_to_human_size` crashing when `:precision` is `nil`.
|
|
48
63
|
|
|
49
|
-
|
|
50
|
-
it would result in keys being lost.
|
|
64
|
+
*Kenta Ishizaki*
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
* Fix `ActiveSupport::InheritableOptions#to_h` to recursively flatten nested
|
|
67
|
+
`InheritableOptions` parents.
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
>> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
|
|
56
|
-
=> {"c" => 1}
|
|
57
|
-
```
|
|
69
|
+
*Andrew Novoselac*
|
|
58
70
|
|
|
59
|
-
|
|
71
|
+
* Fix `ActiveSupport::StructuredEventSubscriber.debug_only` leaking debug-only
|
|
72
|
+
methods across subscriber subclasses.
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
>> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
|
|
63
|
-
=> {"c" => 1, "d" => 2}
|
|
64
|
-
```
|
|
74
|
+
*Kenta Ishizaki*
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
* Fix `ActiveSupport::Inflector#transliterate` mutating the caller's string.
|
|
67
77
|
|
|
68
|
-
*
|
|
78
|
+
*Kenta Ishizaki*
|
|
69
79
|
|
|
70
|
-
|
|
80
|
+
* Fix `Hash.from_xml` raising `Date::Error` on `type="date"` values surrounded
|
|
81
|
+
by whitespace.
|
|
71
82
|
|
|
72
|
-
*
|
|
83
|
+
*Kenta Ishizaki*
|
|
73
84
|
|
|
74
|
-
* Fix
|
|
85
|
+
* Fix `Time#advance` and `DateTime#advance` mutating the options hash passed
|
|
86
|
+
by the caller.
|
|
75
87
|
|
|
76
|
-
|
|
77
|
-
that have been recorded as such in the local store.
|
|
88
|
+
*Kenta Ishizaki*
|
|
78
89
|
|
|
79
|
-
|
|
90
|
+
* Fix `ActiveSupport::Cache::MemoryStore#cleanup` raising `NoMethodError` when
|
|
91
|
+
used with a non-`DupCoder` serializer.
|
|
80
92
|
|
|
81
|
-
*
|
|
93
|
+
*Kenta Ishizaki*
|
|
82
94
|
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
* Fix `String#truncate` with `:separator` misbehaving when the `:omission` is
|
|
96
|
+
longer than the target length.
|
|
85
97
|
|
|
86
|
-
*
|
|
98
|
+
*Kenta Ishizaki*
|
|
87
99
|
|
|
88
|
-
* Fix `
|
|
100
|
+
* Fix `ActiveSupport::Cache::Store#delete_multi` mutating the names array passed
|
|
101
|
+
by the caller.
|
|
89
102
|
|
|
90
|
-
|
|
103
|
+
*Kenta Ishizaki*
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
* Fix `number_to_currency` crashing on a negative number when `:precision` is `nil`.
|
|
93
106
|
|
|
94
|
-
*
|
|
107
|
+
*Kenta Ishizaki*
|
|
95
108
|
|
|
96
|
-
|
|
109
|
+
* Fix `TimeZone#strptime` with `%s` dropping the sub-second fraction of the timestamp.
|
|
97
110
|
|
|
98
|
-
*
|
|
111
|
+
*Kenta Ishizaki*
|
|
99
112
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```
|
|
113
|
+
* Fix `HashWithIndifferentAccess.new` dropping a falsy (`false` or `0`) default
|
|
114
|
+
value from the source hash.
|
|
103
115
|
|
|
104
|
-
|
|
116
|
+
*Kenta Ishizaki*
|
|
105
117
|
|
|
106
|
-
|
|
118
|
+
* Fix `Range#include?` and `Range#===` raising on exclusive non-integer sub-ranges.
|
|
107
119
|
|
|
108
|
-
*
|
|
120
|
+
*Kenta Ishizaki*
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
all previously generated signed messages.
|
|
122
|
+
* Fix `number_to_delimited` corrupting numbers that begin with a `+` or `-` sign.
|
|
112
123
|
|
|
113
|
-
*
|
|
124
|
+
*Kenta Ishizaki*
|
|
114
125
|
|
|
115
|
-
* Fix `
|
|
126
|
+
* Fix `ActiveSupport::InheritableOptions#==` raising `NoMethodError` when compared
|
|
127
|
+
with a non-Hash object.
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```
|
|
129
|
+
*Kenta Ishizaki*
|
|
130
|
+
|
|
131
|
+
* Fix `Enumerable#in_order_of` with `filter: false` dropping elements whose keyed
|
|
132
|
+
value is `nil`.
|
|
122
133
|
|
|
123
|
-
|
|
124
|
-
of the requested 1 hour.
|
|
134
|
+
*Hammad Khan*
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
* Stop the DRb service when shutting down parallel test workers, preventing it
|
|
137
|
+
from lingering after the test run.
|
|
127
138
|
|
|
128
|
-
*
|
|
139
|
+
*Shuta Mugikura*
|
|
129
140
|
|
|
130
|
-
|
|
141
|
+
* Preserve the encoding of `ActiveSupport::SafeBuffer` values round-tripped through
|
|
142
|
+
`ActiveSupport::MessagePack`.
|
|
131
143
|
|
|
132
|
-
*
|
|
144
|
+
*Rafael Mendonça França*
|
|
133
145
|
|
|
134
|
-
|
|
135
|
-
|
|
146
|
+
* Fix `number_to_phone` without an area code stripping a leading delimiter when the
|
|
147
|
+
number itself coincidentally starts with the delimiter string.
|
|
136
148
|
|
|
137
|
-
*
|
|
149
|
+
*Tahsin Hasan*
|
|
138
150
|
|
|
139
|
-
*
|
|
151
|
+
* Update `ActiveSupport::TimeZone` mappings to use the current IANA identifiers
|
|
152
|
+
`Europe/Kyiv` (was `Europe/Kiev`) and `Asia/Yangon` (was `Asia/Rangoon`).
|
|
140
153
|
|
|
141
|
-
|
|
142
|
-
errors are wrapped in `ActionView::Template::Error`.
|
|
154
|
+
*tsymbalenkovlad*
|
|
143
155
|
|
|
144
|
-
|
|
156
|
+
* Use the faster string-based delimiter logic by default in `number_to_delimited`,
|
|
157
|
+
instead of the regular expression fallback.
|
|
158
|
+
|
|
159
|
+
*Shinichi Maeshima*
|
|
145
160
|
|
|
146
|
-
*
|
|
161
|
+
* Preserve the requested key order in `ActiveSupport::Cache::Store#fetch_multi`
|
|
162
|
+
when a local cache is active.
|
|
147
163
|
|
|
148
|
-
|
|
149
|
-
|
|
164
|
+
Previously, if some keys were served from the local cache and others from the
|
|
165
|
+
underlying store, `fetch_multi` returned the local cache hits first instead of
|
|
166
|
+
following the order of the requested keys.
|
|
167
|
+
|
|
168
|
+
*Mueez Afzal*
|
|
169
|
+
|
|
170
|
+
* Fix `String#parameterize` raising `TypeError` when `separator` is `nil`.
|
|
171
|
+
|
|
172
|
+
`parameterize` already treats a `nil` separator the same as an empty one when
|
|
173
|
+
squeezing and trimming separators, but raised `TypeError` before reaching that
|
|
174
|
+
point. A `nil` separator now behaves like `""`, removing the unwanted characters.
|
|
150
175
|
|
|
151
176
|
```ruby
|
|
152
|
-
|
|
153
|
-
mod.module_parent_name # => "Object"
|
|
154
|
-
MyModule::Something = mod
|
|
155
|
-
mod.module_parent_name # => "MyModule"
|
|
177
|
+
"Donald E. Knuth".parameterize(separator: nil) # => "donaldeknuth"
|
|
156
178
|
```
|
|
157
179
|
|
|
158
|
-
*
|
|
180
|
+
*Hammad Khan*
|
|
159
181
|
|
|
160
|
-
*
|
|
182
|
+
* Add `RedisClient::Error` to `ActiveSupport::Cache::RedisCacheStore`'s failsafe rescue list.
|
|
161
183
|
|
|
162
|
-
|
|
184
|
+
The redis-rb gem normally translates `RedisClient::*` errors into `Redis::*` errors but in
|
|
185
|
+
some rare cases, such as when using sentinels, `RedisClient::*` errors may slip through.
|
|
163
186
|
|
|
187
|
+
*David Arrunategui*
|
|
164
188
|
|
|
165
|
-
|
|
189
|
+
* Fix `ActiveSupport::Duration#in_minutes`, `#in_hours`, `#in_days`,
|
|
190
|
+
`#in_weeks`, `#in_months`, and `#in_years` truncating sub-second precision.
|
|
166
191
|
|
|
167
|
-
|
|
192
|
+
These methods divided the duration's integer second count (`in_seconds`,
|
|
193
|
+
aliased to `to_i`) instead of its exact value, so any fractional second was
|
|
194
|
+
silently dropped before the conversion.
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
# Before
|
|
198
|
+
90.5.seconds.in_minutes # => 1.5
|
|
168
199
|
|
|
200
|
+
# After
|
|
201
|
+
90.5.seconds.in_minutes # => 1.5083333333333333
|
|
202
|
+
```
|
|
169
203
|
|
|
170
|
-
|
|
204
|
+
*Kenta Ishizaki*
|
|
171
205
|
|
|
172
|
-
*
|
|
206
|
+
* Fix JSON encoding of non-String Hash keys.
|
|
173
207
|
|
|
208
|
+
The old encoder would simply call `to_s` on them, the newer encoder
|
|
209
|
+
would incorrectly call `as_json` instead.
|
|
174
210
|
|
|
175
|
-
|
|
211
|
+
In the case of `Time`, `DateTime` and `TimeWithZone` this would result
|
|
212
|
+
in different serialization of time keys: `"2009-01-01T12:30:00.000Z"` (arguably better)
|
|
213
|
+
instead of `"2009-01-01 12:30:00 UTC"` (how it used to be).
|
|
176
214
|
|
|
177
|
-
*
|
|
215
|
+
*Kenta Ishizaki*
|
|
178
216
|
|
|
179
|
-
|
|
217
|
+
* Fix `number_to_phone` dropping only the first character of a
|
|
218
|
+
multi-character `:delimiter` when no area code is present.
|
|
180
219
|
|
|
181
|
-
|
|
220
|
+
The leading delimiter produced by an empty first capture group was
|
|
221
|
+
stripped with `slice!(0, 1)`, which assumed a single-character
|
|
222
|
+
delimiter. Multi-character (and multibyte) delimiters now work:
|
|
182
223
|
|
|
183
|
-
|
|
224
|
+
number_to_phone(5551234, delimiter: " - ") # => "555 - 1234"
|
|
225
|
+
# was "- 555 - 1234"
|
|
184
226
|
|
|
227
|
+
*Kenta Ishizaki*
|
|
185
228
|
|
|
186
|
-
|
|
229
|
+
* Fix `titleize` inflector to consider Unicode characters
|
|
187
230
|
|
|
188
|
-
|
|
231
|
+
```ruby
|
|
232
|
+
"ćasim đipa".titleize # => "Ćasim Đipa"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
*Eldin Guzin*
|
|
189
236
|
|
|
190
237
|
|
|
191
|
-
## Rails
|
|
238
|
+
## Rails 8.1.3.1 (July 29, 2026) ##
|
|
192
239
|
|
|
193
240
|
* No changes.
|
|
194
241
|
|
|
195
242
|
|
|
196
|
-
## Rails
|
|
243
|
+
## Rails 8.1.3 (March 24, 2026) ##
|
|
197
244
|
|
|
198
|
-
*
|
|
245
|
+
* Fix `JSONGemCoderEncoder` to correctly serialize custom object hash keys.
|
|
199
246
|
|
|
247
|
+
When hash keys are custom objects whose `as_json` returns a Hash,
|
|
248
|
+
the encoder now calls `to_s` on the original key object instead of
|
|
249
|
+
on the `as_json` result.
|
|
200
250
|
|
|
201
|
-
|
|
251
|
+
Before:
|
|
252
|
+
hash = {CustomKey.new(123) => "value"}
|
|
253
|
+
hash.to_json # => {"{:id=>123}":"value"}
|
|
202
254
|
|
|
203
|
-
|
|
255
|
+
After:
|
|
256
|
+
hash.to_json # => {"custom_123":"value"}
|
|
204
257
|
|
|
205
|
-
|
|
206
|
-
class Person
|
|
207
|
-
delegate_missing_to :address, allow_nil: true
|
|
258
|
+
*Dan Sharp*
|
|
208
259
|
|
|
209
|
-
|
|
210
|
-
nil
|
|
211
|
-
end
|
|
260
|
+
* Fix inflections to better handle overlapping acronyms.
|
|
212
261
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
262
|
+
```ruby
|
|
263
|
+
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
264
|
+
inflect.acronym "USD"
|
|
265
|
+
inflect.acronym "USDC"
|
|
216
266
|
end
|
|
217
267
|
|
|
218
|
-
|
|
219
|
-
Person.new.berliner? # undefined local variable or method `city' for an instance of Person (NameError)
|
|
268
|
+
"USDC".underscore # => "usdc"
|
|
220
269
|
```
|
|
221
270
|
|
|
271
|
+
*Said Kaldybaev*
|
|
272
|
+
|
|
273
|
+
* Silence Dalli 4.0+ warning when using `ActiveSupport::Cache::MemCacheStore`.
|
|
274
|
+
|
|
275
|
+
*zzak*
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
## Rails 8.1.2.1 (March 23, 2026) ##
|
|
279
|
+
|
|
280
|
+
* Reject scientific notation in NumberConverter
|
|
281
|
+
|
|
282
|
+
[CVE-2026-33176]
|
|
283
|
+
|
|
222
284
|
*Jean Boussier*
|
|
223
285
|
|
|
224
|
-
*
|
|
286
|
+
* Fix `SafeBuffer#%` to preserve unsafe status
|
|
225
287
|
|
|
226
|
-
|
|
288
|
+
[CVE-2026-33170]
|
|
227
289
|
|
|
228
|
-
*
|
|
290
|
+
*Jean Boussier*
|
|
229
291
|
|
|
230
|
-
|
|
292
|
+
* Improve performance of NumberToDelimitedConverter
|
|
293
|
+
|
|
294
|
+
[CVE-2026-33169]
|
|
295
|
+
|
|
296
|
+
*Jean Boussier*
|
|
231
297
|
|
|
232
|
-
* Support `duration` type in `ActiveSupport::XmlMini`.
|
|
233
298
|
|
|
234
|
-
|
|
299
|
+
## Rails 8.1.2 (January 08, 2026) ##
|
|
235
300
|
|
|
236
|
-
*
|
|
301
|
+
* Make `delegate` and `delegate_missing_to` work in BasicObject subclasses.
|
|
237
302
|
|
|
238
303
|
*Rafael Mendonça França*
|
|
239
304
|
|
|
240
|
-
*
|
|
305
|
+
* Fix Inflectors when using a locale that fallbacks to `:en`.
|
|
241
306
|
|
|
242
|
-
|
|
243
|
-
- `deprecate_constant`
|
|
244
|
-
- `ActiveSupport::Deprecation::DeprecatedObjectProxy.new`
|
|
245
|
-
- `ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new`
|
|
246
|
-
- `ActiveSupport::Deprecation::DeprecatedConstantProxy.new`
|
|
247
|
-
- `assert_deprecated`
|
|
248
|
-
- `assert_not_deprecated`
|
|
249
|
-
- `collect_deprecations`
|
|
307
|
+
*Said Kaldybaev*
|
|
250
308
|
|
|
251
|
-
|
|
309
|
+
* Fix `ActiveSupport::TimeWithZone#as_json` to consistently return UTF-8 strings.
|
|
252
310
|
|
|
253
|
-
|
|
311
|
+
Previously the returned string would sometime be encoded in US-ASCII, which in
|
|
312
|
+
some cases may be problematic.
|
|
254
313
|
|
|
255
|
-
|
|
314
|
+
Now the method consistently always return UTF-8 strings.
|
|
256
315
|
|
|
257
|
-
*
|
|
316
|
+
*Jean Boussier*
|
|
258
317
|
|
|
259
|
-
|
|
318
|
+
* Fix `TimeWithZone#xmlschema` when wrapping a `DateTime` instance in local time.
|
|
260
319
|
|
|
261
|
-
|
|
320
|
+
Previously it would return an invalid time.
|
|
262
321
|
|
|
263
|
-
*
|
|
322
|
+
*Dmytro Rymar*
|
|
264
323
|
|
|
265
|
-
*
|
|
324
|
+
* Implement LocalCache strategy on `ActiveSupport::Cache::MemoryStore`. The memory store
|
|
325
|
+
needs to respond to the same interface as other cache stores (e.g. `ActiveSupport::NullStore`).
|
|
266
326
|
|
|
267
|
-
*
|
|
327
|
+
*Mikey Gough*
|
|
268
328
|
|
|
269
|
-
*
|
|
329
|
+
* Fix `ActiveSupport::Inflector.humanize` with international characters.
|
|
270
330
|
|
|
271
|
-
|
|
331
|
+
```ruby
|
|
332
|
+
ActiveSupport::Inflector.humanize("áÉÍÓÚ") # => "Áéíóú"
|
|
333
|
+
ActiveSupport::Inflector.humanize("аБВГДЕ") # => "Абвгде"
|
|
334
|
+
```
|
|
272
335
|
|
|
273
|
-
*
|
|
336
|
+
*Jose Luis Duran*
|
|
274
337
|
|
|
275
|
-
*Rafael Mendonça França*
|
|
276
338
|
|
|
277
|
-
|
|
339
|
+
## Rails 8.1.1 (October 28, 2025) ##
|
|
278
340
|
|
|
279
|
-
|
|
341
|
+
* No changes.
|
|
280
342
|
|
|
281
|
-
|
|
343
|
+
|
|
344
|
+
## Rails 8.1.0 (October 22, 2025) ##
|
|
345
|
+
|
|
346
|
+
* Remove deprecated passing a Time object to `Time#since`.
|
|
282
347
|
|
|
283
348
|
*Rafael Mendonça França*
|
|
284
349
|
|
|
285
|
-
* Remove deprecated
|
|
350
|
+
* Remove deprecated `Benchmark.ms` method. It is now defined in the `benchmark` gem.
|
|
286
351
|
|
|
287
352
|
*Rafael Mendonça França*
|
|
288
353
|
|
|
289
|
-
* Remove deprecated
|
|
354
|
+
* Remove deprecated addition for `Time` instances with `ActiveSupport::TimeWithZone`.
|
|
290
355
|
|
|
291
356
|
*Rafael Mendonça França*
|
|
292
357
|
|
|
293
|
-
* Remove deprecated
|
|
358
|
+
* Remove deprecated support for `to_time` to preserve the system local time. It will now always preserve the receiver
|
|
359
|
+
timezone.
|
|
294
360
|
|
|
295
361
|
*Rafael Mendonça França*
|
|
296
362
|
|
|
297
|
-
*
|
|
363
|
+
* Deprecate `config.active_support.to_time_preserves_timezone`.
|
|
298
364
|
|
|
299
|
-
|
|
300
|
-
This is helpful in detecting broken tests that do not perform intended assertions.
|
|
365
|
+
*Rafael Mendonça França*
|
|
301
366
|
|
|
302
|
-
|
|
367
|
+
* Standardize event name formatting in `assert_event_reported` error messages.
|
|
303
368
|
|
|
304
|
-
|
|
369
|
+
The event name in failure messages now uses `.inspect` (e.g., `name: "user.created"`)
|
|
370
|
+
to match `assert_events_reported` and provide type clarity between strings and symbols.
|
|
371
|
+
This only affects tests that assert on the failure message format itself.
|
|
305
372
|
|
|
306
|
-
*
|
|
373
|
+
*George Ma*
|
|
307
374
|
|
|
308
|
-
*
|
|
375
|
+
* Fix `Enumerable#sole` to return the full tuple instead of just the first element of the tuple.
|
|
309
376
|
|
|
310
|
-
*
|
|
377
|
+
*Olivier Bellone*
|
|
378
|
+
|
|
379
|
+
* Fix parallel tests hanging when worker processes die abruptly.
|
|
311
380
|
|
|
312
|
-
|
|
381
|
+
Previously, if a worker process was killed (e.g., OOM killed, `kill -9`) during parallel
|
|
382
|
+
test execution, the test suite would hang forever waiting for the dead worker.
|
|
313
383
|
|
|
314
|
-
*
|
|
384
|
+
*Joshua Young*
|
|
315
385
|
|
|
316
|
-
*
|
|
386
|
+
* Add `config.active_support.escape_js_separators_in_json`.
|
|
317
387
|
|
|
318
|
-
|
|
319
|
-
causing state to leak.
|
|
388
|
+
Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.
|
|
320
389
|
|
|
321
|
-
|
|
390
|
+
Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
|
|
391
|
+
As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
|
|
322
392
|
|
|
323
|
-
|
|
393
|
+
*Étienne Barrié*, *Jean Boussier*
|
|
324
394
|
|
|
325
|
-
|
|
395
|
+
* Fix `NameError` when `class_attribute` is defined on instance singleton classes.
|
|
326
396
|
|
|
327
|
-
|
|
397
|
+
Previously, calling `class_attribute` on an instance's singleton class would raise
|
|
398
|
+
a `NameError` when accessing the attribute through the instance.
|
|
328
399
|
|
|
329
400
|
```ruby
|
|
330
|
-
|
|
331
|
-
|
|
401
|
+
object = MyClass.new
|
|
402
|
+
object.singleton_class.class_attribute :foo, default: "bar"
|
|
403
|
+
object.foo # previously raised NameError, now returns "bar"
|
|
332
404
|
```
|
|
333
405
|
|
|
334
|
-
*
|
|
406
|
+
*Joshua Young*
|
|
335
407
|
|
|
336
|
-
*
|
|
337
|
-
|
|
408
|
+
* Introduce `ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting`
|
|
409
|
+
to enable event reporter debug mode in tests.
|
|
338
410
|
|
|
339
|
-
|
|
340
|
-
|
|
411
|
+
The previous way to enable debug mode is by using `#with_debug` on the
|
|
412
|
+
event reporter itself, which is too verbose. This new helper will help
|
|
413
|
+
clear up any confusion on how to test debug events.
|
|
341
414
|
|
|
342
|
-
*
|
|
415
|
+
*Gannon McGibbon*
|
|
343
416
|
|
|
344
|
-
* Add `
|
|
417
|
+
* Add `ActiveSupport::StructuredEventSubscriber` for consuming notifications and
|
|
418
|
+
emitting structured event logs. Events may be emitted with the `#emit_event`
|
|
419
|
+
or `#emit_debug_event` methods.
|
|
345
420
|
|
|
346
421
|
```ruby
|
|
347
|
-
class
|
|
348
|
-
|
|
422
|
+
class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber
|
|
423
|
+
def notification(event)
|
|
424
|
+
emit_event("my.notification", data: 1)
|
|
425
|
+
end
|
|
349
426
|
end
|
|
350
427
|
```
|
|
351
428
|
|
|
352
|
-
*
|
|
429
|
+
*Adrianna Chang*
|
|
430
|
+
|
|
431
|
+
* `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unecessary reloads with time travel test helpers
|
|
432
|
+
|
|
433
|
+
*Jan Grodowski*
|
|
434
|
+
|
|
435
|
+
* Add `ActiveSupport::Cache::Store#namespace=` and `#namespace`.
|
|
436
|
+
|
|
437
|
+
Can be used as an alternative to `Store#clear` in some situations such as parallel
|
|
438
|
+
testing.
|
|
439
|
+
|
|
440
|
+
*Nick Schwaderer*
|
|
441
|
+
|
|
442
|
+
* Create `parallel_worker_id` helper for running parallel tests. This allows users to
|
|
443
|
+
know which worker they are currently running in.
|
|
444
|
+
|
|
445
|
+
*Nick Schwaderer*
|
|
446
|
+
|
|
447
|
+
* Make the cache of `ActiveSupport::Cache::Strategy::LocalCache::Middleware` updatable.
|
|
448
|
+
|
|
449
|
+
If the cache client at `Rails.cache` of a booted application changes, the corresponding
|
|
450
|
+
mounted middleware needs to update in order for request-local caches to be setup properly.
|
|
451
|
+
Otherwise, redundant cache operations will erroneously hit the datastore.
|
|
353
452
|
|
|
354
|
-
*
|
|
453
|
+
*Gannon McGibbon*
|
|
454
|
+
|
|
455
|
+
* Add `assert_events_reported` test helper for `ActiveSupport::EventReporter`.
|
|
456
|
+
|
|
457
|
+
This new assertion allows testing multiple events in a single block, regardless of order:
|
|
355
458
|
|
|
356
459
|
```ruby
|
|
357
|
-
|
|
358
|
-
|
|
460
|
+
assert_events_reported([
|
|
461
|
+
{ name: "user.created", payload: { id: 123 } },
|
|
462
|
+
{ name: "email.sent", payload: { to: "user@example.com" } }
|
|
463
|
+
]) do
|
|
464
|
+
create_user_and_send_welcome_email
|
|
359
465
|
end
|
|
360
466
|
```
|
|
361
467
|
|
|
362
|
-
*
|
|
468
|
+
*George Ma*
|
|
363
469
|
|
|
364
|
-
*
|
|
365
|
-
default number of workers when parallelizing tests.
|
|
470
|
+
* Add `ActiveSupport::TimeZone#standard_name` method.
|
|
366
471
|
|
|
367
|
-
|
|
472
|
+
``` ruby
|
|
473
|
+
zone = ActiveSupport::TimeZone['Hawaii']
|
|
474
|
+
# Old way
|
|
475
|
+
ActiveSupport::TimeZone::MAPPING[zone.name]
|
|
476
|
+
# New way
|
|
477
|
+
zone.standard_name # => 'Pacific/Honolulu'
|
|
478
|
+
```
|
|
368
479
|
|
|
369
|
-
*
|
|
480
|
+
*Bogdan Gusiev*
|
|
370
481
|
|
|
371
|
-
|
|
372
|
-
it remembers a timezone of its argument, and all stubbed methods start
|
|
373
|
-
returning results in that remembered timezone. However, the expected
|
|
374
|
-
behavior is to return results in a system timezone.
|
|
482
|
+
* Add Structured Event Reporter, accessible via `Rails.event`.
|
|
375
483
|
|
|
376
|
-
|
|
484
|
+
The Event Reporter provides a unified interface for producing structured events in Rails
|
|
485
|
+
applications:
|
|
377
486
|
|
|
378
|
-
|
|
487
|
+
```ruby
|
|
488
|
+
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
|
|
489
|
+
```
|
|
379
490
|
|
|
380
|
-
|
|
491
|
+
It supports adding tags to events:
|
|
381
492
|
|
|
382
493
|
```ruby
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
494
|
+
Rails.event.tagged("graphql") do
|
|
495
|
+
# Event includes tags: { graphql: true }
|
|
496
|
+
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
|
|
497
|
+
end
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
As well as context:
|
|
501
|
+
```ruby
|
|
502
|
+
# All events will contain context: {request_id: "abc123", shop_id: 456}
|
|
503
|
+
Rails.event.set_context(request_id: "abc123", shop_id: 456)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Events are emitted to subscribers. Applications register subscribers to
|
|
507
|
+
control how events are serialized and emitted. Subscribers must implement
|
|
508
|
+
an `#emit` method, which receives the event hash:
|
|
509
|
+
|
|
510
|
+
```ruby
|
|
511
|
+
class LogSubscriber
|
|
512
|
+
def emit(event)
|
|
513
|
+
payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
|
|
514
|
+
source_location = event[:source_location]
|
|
515
|
+
log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
|
|
516
|
+
Rails.logger.info(log)
|
|
387
517
|
end
|
|
388
|
-
# ...
|
|
389
518
|
end
|
|
390
519
|
```
|
|
391
520
|
|
|
392
|
-
|
|
521
|
+
*Adrianna Chang*
|
|
522
|
+
|
|
523
|
+
* Make `ActiveSupport::Logger` `#freeze`-friendly.
|
|
524
|
+
|
|
525
|
+
*Joshua Young*
|
|
526
|
+
|
|
527
|
+
* Make `ActiveSupport::Gzip.compress` deterministic based on input.
|
|
528
|
+
|
|
529
|
+
`ActiveSupport::Gzip.compress` used to include a timestamp in the output,
|
|
530
|
+
causing consecutive calls with the same input data to have different output
|
|
531
|
+
if called during different seconds. It now always sets the timestamp to `0`
|
|
532
|
+
so that the output is identical for any given input.
|
|
533
|
+
|
|
534
|
+
*Rob Brackett*
|
|
535
|
+
|
|
536
|
+
* Given an array of `Thread::Backtrace::Location` objects, the new method
|
|
537
|
+
`ActiveSupport::BacktraceCleaner#clean_locations` returns an array with the
|
|
538
|
+
clean ones:
|
|
539
|
+
|
|
540
|
+
```ruby
|
|
541
|
+
clean_locations = backtrace_cleaner.clean_locations(caller_locations)
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
Filters and silencers receive strings as usual. However, the `path`
|
|
545
|
+
attributes of the locations in the returned array are the original,
|
|
546
|
+
unfiltered ones, since locations are immutable.
|
|
547
|
+
|
|
548
|
+
*Xavier Noria*
|
|
549
|
+
|
|
550
|
+
* Improve `CurrentAttributes` and `ExecutionContext` state managment in test cases.
|
|
551
|
+
|
|
552
|
+
Previously these two global state would be entirely cleared out whenever calling
|
|
553
|
+
into code that is wrapped by the Rails executor, typically Action Controller or
|
|
554
|
+
Active Job helpers:
|
|
555
|
+
|
|
556
|
+
```ruby
|
|
557
|
+
test "#index works" do
|
|
558
|
+
CurrentUser.id = 42
|
|
559
|
+
get :index
|
|
560
|
+
CurrentUser.id == nil
|
|
561
|
+
end
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
Now re-entering the executor properly save and restore that state.
|
|
393
565
|
|
|
394
566
|
*Jean Boussier*
|
|
395
567
|
|
|
396
|
-
*
|
|
568
|
+
* The new method `ActiveSupport::BacktraceCleaner#first_clean_location`
|
|
569
|
+
returns the first clean location of the caller's call stack, or `nil`.
|
|
570
|
+
Locations are `Thread::Backtrace::Location` objects. Useful when you want to
|
|
571
|
+
report the application-level location where something happened as an object.
|
|
397
572
|
|
|
398
|
-
*
|
|
573
|
+
*Xavier Noria*
|
|
399
574
|
|
|
400
|
-
*
|
|
575
|
+
* FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.
|
|
401
576
|
|
|
402
|
-
|
|
403
|
-
`nil` if there was an error talking to the cache backend, and `false` if the write failed
|
|
404
|
-
for another reason (e.g. the key already exists and `unless_exist: true` was passed).
|
|
577
|
+
*Ermolaev Andrey*, *zzak*
|
|
405
578
|
|
|
406
|
-
|
|
579
|
+
* The new method `ActiveSupport::BacktraceCleaner#first_clean_frame` returns
|
|
580
|
+
the first clean frame of the caller's backtrace, or `nil`. Useful when you
|
|
581
|
+
want to report the application-level frame where something happened as a
|
|
582
|
+
string.
|
|
407
583
|
|
|
408
|
-
*
|
|
584
|
+
*Xavier Noria*
|
|
409
585
|
|
|
410
|
-
|
|
586
|
+
* Always clear `CurrentAttributes` instances.
|
|
411
587
|
|
|
412
|
-
|
|
588
|
+
Previously `CurrentAttributes` instance would be reset at the end of requests.
|
|
589
|
+
Meaning its attributes would be re-initialized.
|
|
413
590
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
591
|
+
This is problematic because it assume these objects don't hold any state
|
|
592
|
+
other than their declared attribute, which isn't always the case, and
|
|
593
|
+
can lead to state leak across request.
|
|
417
594
|
|
|
418
|
-
|
|
595
|
+
Now `CurrentAttributes` instances are abandoned at the end of a request,
|
|
596
|
+
and a new instance is created at the start of the next request.
|
|
419
597
|
|
|
420
|
-
*
|
|
598
|
+
*Jean Boussier*, *Janko Marohnić*
|
|
421
599
|
|
|
422
|
-
|
|
600
|
+
* Add public API for `before_fork_hook` in parallel testing.
|
|
423
601
|
|
|
424
|
-
|
|
602
|
+
Introduces a public API for calling the before fork hooks implemented by parallel testing.
|
|
425
603
|
|
|
426
|
-
|
|
604
|
+
```ruby
|
|
605
|
+
parallelize_before_fork do
|
|
606
|
+
# perform an action before test processes are forked
|
|
607
|
+
end
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
*Eileen M. Uchitelle*
|
|
611
|
+
|
|
612
|
+
* Implement ability to skip creating parallel testing databases.
|
|
613
|
+
|
|
614
|
+
With parallel testing, Rails will create a database per process. If this isn't
|
|
615
|
+
desirable or you would like to implement databases handling on your own, you can
|
|
616
|
+
now turn off this default behavior.
|
|
617
|
+
|
|
618
|
+
To skip creating a database per process, you can change it via the
|
|
619
|
+
`parallelize` method:
|
|
620
|
+
|
|
621
|
+
```ruby
|
|
622
|
+
parallelize(workers: 10, parallelize_databases: false)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
or via the application configuration:
|
|
626
|
+
|
|
627
|
+
```ruby
|
|
628
|
+
config.active_support.parallelize_databases = false
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
*Eileen M. Uchitelle*
|
|
632
|
+
|
|
633
|
+
* Allow to configure maximum cache key sizes
|
|
634
|
+
|
|
635
|
+
When the key exceeds the configured limit (250 bytes by default), it will be truncated and
|
|
636
|
+
the digest of the rest of the key appended to it.
|
|
637
|
+
|
|
638
|
+
Note that previously `ActiveSupport::Cache::RedisCacheStore` allowed up to 1kb cache keys before
|
|
639
|
+
truncation, which is now reduced to 250 bytes.
|
|
427
640
|
|
|
428
|
-
|
|
641
|
+
```ruby
|
|
642
|
+
config.cache_store = :redis_cache_store, { max_key_size: 64 }
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
*fatkodima*
|
|
646
|
+
|
|
647
|
+
* Use `UNLINK` command instead of `DEL` in `ActiveSupport::Cache::RedisCacheStore` for non-blocking deletion.
|
|
648
|
+
|
|
649
|
+
*Aron Roh*
|
|
650
|
+
|
|
651
|
+
* Add `Cache#read_counter` and `Cache#write_counter`
|
|
652
|
+
|
|
653
|
+
```ruby
|
|
654
|
+
Rails.cache.write_counter("foo", 1)
|
|
655
|
+
Rails.cache.read_counter("foo") # => 1
|
|
656
|
+
Rails.cache.increment("foo")
|
|
657
|
+
Rails.cache.read_counter("foo") # => 2
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
*Alex Ghiculescu*
|
|
661
|
+
|
|
662
|
+
* Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports
|
|
663
|
+
|
|
664
|
+
Captures all reported errors from within the block that match the given
|
|
665
|
+
error class.
|
|
666
|
+
|
|
667
|
+
```ruby
|
|
668
|
+
reports = capture_error_reports(IOError) do
|
|
669
|
+
Rails.error.report(IOError.new("Oops"))
|
|
670
|
+
Rails.error.report(IOError.new("Oh no"))
|
|
671
|
+
Rails.error.report(StandardError.new)
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
assert_equal 2, reports.size
|
|
675
|
+
assert_equal "Oops", reports.first.error.message
|
|
676
|
+
assert_equal "Oh no", reports.last.error.message
|
|
677
|
+
```
|
|
429
678
|
|
|
430
679
|
*Andrew Novoselac*
|
|
431
680
|
|
|
432
|
-
*
|
|
681
|
+
* Introduce ActiveSupport::ErrorReporter#add_middleware
|
|
682
|
+
|
|
683
|
+
When reporting an error, the error context middleware will be called with the reported error
|
|
684
|
+
and base execution context. The stack may mutate the context hash. The mutated context will
|
|
685
|
+
then be passed to error subscribers. Middleware receives the same parameters as `ErrorReporter#report`.
|
|
686
|
+
|
|
687
|
+
*Andrew Novoselac*, *Sam Schmidt*
|
|
688
|
+
|
|
689
|
+
* Change execution wrapping to report all exceptions, including `Exception`.
|
|
690
|
+
|
|
691
|
+
If a more serious error like `SystemStackError` or `NoMemoryError` happens,
|
|
692
|
+
the error reporter should be able to report these kinds of exceptions.
|
|
693
|
+
|
|
694
|
+
*Gannon McGibbon*
|
|
695
|
+
|
|
696
|
+
* `ActiveSupport::Testing::Parallelization.before_fork_hook` allows declaration of callbacks that
|
|
697
|
+
are invoked immediately before forking test workers.
|
|
698
|
+
|
|
699
|
+
*Mike Dalessio*
|
|
700
|
+
|
|
701
|
+
* Allow the `#freeze_time` testing helper to accept a date or time argument.
|
|
702
|
+
|
|
703
|
+
```ruby
|
|
704
|
+
Time.current # => Sun, 09 Jul 2024 15:34:49 EST -05:00
|
|
705
|
+
freeze_time Time.current + 1.day
|
|
706
|
+
sleep 1
|
|
707
|
+
Time.current # => Mon, 10 Jul 2024 15:34:49 EST -05:00
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
*Joshua Young*
|
|
711
|
+
|
|
712
|
+
* `ActiveSupport::JSON` now accepts options
|
|
713
|
+
|
|
714
|
+
It is now possible to pass options to `ActiveSupport::JSON`:
|
|
715
|
+
```ruby
|
|
716
|
+
ActiveSupport::JSON.decode('{"key": "value"}', symbolize_names: true) # => { key: "value" }
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
*matthaigh27*
|
|
720
|
+
|
|
721
|
+
* `ActiveSupport::Testing::NotificationAssertions`'s `assert_notification` now matches against payload subsets by default.
|
|
722
|
+
|
|
723
|
+
Previously the following assertion would fail due to excess key vals in the notification payload. Now with payload subset matching, it will pass.
|
|
724
|
+
|
|
725
|
+
```ruby
|
|
726
|
+
assert_notification("post.submitted", title: "Cool Post") do
|
|
727
|
+
ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: "Cool Body")
|
|
728
|
+
end
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
Additionally, you can now persist a matched notification for more customized assertions.
|
|
732
|
+
|
|
733
|
+
```ruby
|
|
734
|
+
notification = assert_notification("post.submitted", title: "Cool Post") do
|
|
735
|
+
ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: Body.new("Cool Body"))
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
assert_instance_of(Body, notification.payload[:body])
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
*Nicholas La Roux*
|
|
742
|
+
|
|
743
|
+
* Deprecate `String#mb_chars` and `ActiveSupport::Multibyte::Chars`.
|
|
744
|
+
|
|
745
|
+
These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
|
|
746
|
+
aware. There is no legitimate reasons to need these APIs today.
|
|
747
|
+
|
|
748
|
+
*Jean Boussier*
|
|
749
|
+
|
|
750
|
+
* Deprecate `ActiveSupport::Configurable`
|
|
751
|
+
|
|
752
|
+
*Sean Doyle*
|
|
753
|
+
|
|
754
|
+
* `nil.to_query("key")` now returns `key`.
|
|
755
|
+
|
|
756
|
+
Previously it would return `key=`, preventing round tripping with `Rack::Utils.parse_nested_query`.
|
|
757
|
+
|
|
758
|
+
*Erol Fornoles*
|
|
759
|
+
|
|
760
|
+
* Avoid wrapping redis in a `ConnectionPool` when using `ActiveSupport::Cache::RedisCacheStore` if the `:redis`
|
|
761
|
+
option is already a `ConnectionPool`.
|
|
762
|
+
|
|
763
|
+
*Joshua Young*
|
|
764
|
+
|
|
765
|
+
* Alter `ERB::Util.tokenize` to return :PLAIN token with full input string when string doesn't contain ERB tags.
|
|
433
766
|
|
|
434
|
-
|
|
435
|
-
`SemanticLogger#level` returns a Symbol while stdlib `Logger#level` returns an Integer.
|
|
767
|
+
*Martin Emde*
|
|
436
768
|
|
|
437
|
-
|
|
438
|
-
`SemanticLogger` instance.
|
|
769
|
+
* Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceded by multibyte characters.
|
|
439
770
|
|
|
440
|
-
*
|
|
771
|
+
*Martin Emde*
|
|
441
772
|
|
|
442
|
-
*
|
|
773
|
+
* Add `ActiveSupport::Testing::NotificationAssertions` module to help with testing `ActiveSupport::Notifications`.
|
|
443
774
|
|
|
444
|
-
*
|
|
775
|
+
*Nicholas La Roux*, *Yishu See*, *Sean Doyle*
|
|
445
776
|
|
|
446
|
-
*
|
|
777
|
+
* `ActiveSupport::CurrentAttributes#attributes` now will return a new hash object on each call.
|
|
447
778
|
|
|
448
|
-
Previously,
|
|
449
|
-
method from the `Hash` class, which was not able to access values using indifferent keys.
|
|
779
|
+
Previously, the same hash object was returned each time that method was called.
|
|
450
780
|
|
|
451
781
|
*fatkodima*
|
|
452
782
|
|
|
453
|
-
|
|
783
|
+
* `ActiveSupport::JSON.encode` supports CIDR notation.
|
|
784
|
+
|
|
785
|
+
Previously:
|
|
786
|
+
|
|
787
|
+
```ruby
|
|
788
|
+
ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0\""
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
After this change:
|
|
792
|
+
|
|
793
|
+
```ruby
|
|
794
|
+
ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0/24\""
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
*Taketo Takashima*
|
|
798
|
+
|
|
799
|
+
* Make `ActiveSupport::FileUpdateChecker` faster when checking many file-extensions.
|
|
800
|
+
|
|
801
|
+
*Jonathan del Strother*
|
|
802
|
+
|
|
803
|
+
Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/activesupport/CHANGELOG.md) for previous changes.
|