activesupport 7.0.8 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +821 -291
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_support/actionable_error.rb +3 -1
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +25 -5
  8. data/lib/active_support/benchmarkable.rb +1 -0
  9. data/lib/active_support/broadcast_logger.rb +242 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +128 -0
  13. data/lib/active_support/cache/file_store.rb +36 -9
  14. data/lib/active_support/cache/mem_cache_store.rb +84 -68
  15. data/lib/active_support/cache/memory_store.rb +75 -21
  16. data/lib/active_support/cache/null_store.rb +6 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +134 -131
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +20 -8
  20. data/lib/active_support/cache.rb +298 -246
  21. data/lib/active_support/callbacks.rb +44 -21
  22. data/lib/active_support/concern.rb +4 -2
  23. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
  24. data/lib/active_support/concurrency/null_lock.rb +13 -0
  25. data/lib/active_support/configurable.rb +10 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +2 -1
  27. data/lib/active_support/core_ext/array.rb +0 -1
  28. data/lib/active_support/core_ext/class/subclasses.rb +13 -10
  29. data/lib/active_support/core_ext/date/conversions.rb +1 -0
  30. data/lib/active_support/core_ext/date.rb +0 -1
  31. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  32. data/lib/active_support/core_ext/date_time/conversions.rb +6 -2
  33. data/lib/active_support/core_ext/date_time.rb +0 -1
  34. data/lib/active_support/core_ext/digest/uuid.rb +1 -10
  35. data/lib/active_support/core_ext/enumerable.rb +3 -75
  36. data/lib/active_support/core_ext/erb/util.rb +196 -0
  37. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  38. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  39. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  40. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  41. data/lib/active_support/core_ext/module/delegation.rb +40 -11
  42. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  43. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  44. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  45. data/lib/active_support/core_ext/numeric/conversions.rb +2 -0
  46. data/lib/active_support/core_ext/numeric.rb +0 -1
  47. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  48. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  49. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  50. data/lib/active_support/core_ext/object/json.rb +11 -3
  51. data/lib/active_support/core_ext/object/with.rb +44 -0
  52. data/lib/active_support/core_ext/object/with_options.rb +3 -3
  53. data/lib/active_support/core_ext/object.rb +1 -0
  54. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  55. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  56. data/lib/active_support/core_ext/pathname.rb +1 -0
  57. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  58. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  59. data/lib/active_support/core_ext/range.rb +1 -2
  60. data/lib/active_support/core_ext/securerandom.rb +24 -12
  61. data/lib/active_support/core_ext/string/filters.rb +20 -14
  62. data/lib/active_support/core_ext/string/inflections.rb +16 -5
  63. data/lib/active_support/core_ext/string/output_safety.rb +38 -174
  64. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  65. data/lib/active_support/core_ext/time/calculations.rb +18 -2
  66. data/lib/active_support/core_ext/time/conversions.rb +2 -2
  67. data/lib/active_support/core_ext/time/zones.rb +4 -4
  68. data/lib/active_support/core_ext/time.rb +0 -1
  69. data/lib/active_support/current_attributes.rb +15 -6
  70. data/lib/active_support/deep_mergeable.rb +53 -0
  71. data/lib/active_support/dependencies/autoload.rb +17 -12
  72. data/lib/active_support/deprecation/behaviors.rb +55 -34
  73. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  74. data/lib/active_support/deprecation/deprecators.rb +104 -0
  75. data/lib/active_support/deprecation/disallowed.rb +3 -5
  76. data/lib/active_support/deprecation/instance_delegator.rb +31 -4
  77. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  78. data/lib/active_support/deprecation/proxy_wrappers.rb +37 -22
  79. data/lib/active_support/deprecation/reporting.rb +35 -21
  80. data/lib/active_support/deprecation.rb +32 -5
  81. data/lib/active_support/deprecator.rb +7 -0
  82. data/lib/active_support/descendants_tracker.rb +104 -132
  83. data/lib/active_support/duration/iso8601_serializer.rb +0 -2
  84. data/lib/active_support/duration.rb +2 -1
  85. data/lib/active_support/encrypted_configuration.rb +30 -9
  86. data/lib/active_support/encrypted_file.rb +8 -3
  87. data/lib/active_support/environment_inquirer.rb +22 -2
  88. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  89. data/lib/active_support/error_reporter.rb +121 -35
  90. data/lib/active_support/execution_wrapper.rb +4 -4
  91. data/lib/active_support/file_update_checker.rb +4 -2
  92. data/lib/active_support/fork_tracker.rb +10 -2
  93. data/lib/active_support/gem_version.rb +3 -3
  94. data/lib/active_support/gzip.rb +2 -0
  95. data/lib/active_support/hash_with_indifferent_access.rb +35 -17
  96. data/lib/active_support/i18n.rb +1 -1
  97. data/lib/active_support/i18n_railtie.rb +20 -13
  98. data/lib/active_support/inflector/inflections.rb +2 -0
  99. data/lib/active_support/inflector/methods.rb +22 -10
  100. data/lib/active_support/inflector/transliterate.rb +3 -1
  101. data/lib/active_support/isolated_execution_state.rb +26 -22
  102. data/lib/active_support/json/decoding.rb +2 -1
  103. data/lib/active_support/json/encoding.rb +25 -43
  104. data/lib/active_support/key_generator.rb +9 -1
  105. data/lib/active_support/lazy_load_hooks.rb +6 -4
  106. data/lib/active_support/locale/en.yml +2 -0
  107. data/lib/active_support/log_subscriber.rb +78 -33
  108. data/lib/active_support/logger.rb +9 -60
  109. data/lib/active_support/logger_thread_safe_level.rb +10 -24
  110. data/lib/active_support/message_encryptor.rb +197 -53
  111. data/lib/active_support/message_encryptors.rb +141 -0
  112. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  113. data/lib/active_support/message_pack/extensions.rb +292 -0
  114. data/lib/active_support/message_pack/serializer.rb +63 -0
  115. data/lib/active_support/message_pack.rb +50 -0
  116. data/lib/active_support/message_verifier.rb +212 -93
  117. data/lib/active_support/message_verifiers.rb +135 -0
  118. data/lib/active_support/messages/codec.rb +65 -0
  119. data/lib/active_support/messages/metadata.rb +111 -45
  120. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  121. data/lib/active_support/messages/rotator.rb +34 -32
  122. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  123. data/lib/active_support/multibyte/chars.rb +2 -0
  124. data/lib/active_support/multibyte/unicode.rb +9 -37
  125. data/lib/active_support/notifications/fanout.rb +239 -81
  126. data/lib/active_support/notifications/instrumenter.rb +77 -20
  127. data/lib/active_support/notifications.rb +1 -1
  128. data/lib/active_support/number_helper/number_converter.rb +14 -5
  129. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  130. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  131. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  132. data/lib/active_support/ordered_hash.rb +3 -3
  133. data/lib/active_support/ordered_options.rb +14 -0
  134. data/lib/active_support/parameter_filter.rb +84 -69
  135. data/lib/active_support/proxy_object.rb +2 -0
  136. data/lib/active_support/railtie.rb +33 -21
  137. data/lib/active_support/reloader.rb +12 -4
  138. data/lib/active_support/rescuable.rb +2 -0
  139. data/lib/active_support/secure_compare_rotator.rb +16 -9
  140. data/lib/active_support/string_inquirer.rb +3 -1
  141. data/lib/active_support/subscriber.rb +9 -27
  142. data/lib/active_support/syntax_error_proxy.rb +49 -0
  143. data/lib/active_support/tagged_logging.rb +60 -24
  144. data/lib/active_support/test_case.rb +153 -6
  145. data/lib/active_support/testing/assertions.rb +25 -9
  146. data/lib/active_support/testing/autorun.rb +0 -2
  147. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  148. data/lib/active_support/testing/deprecation.rb +25 -25
  149. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  150. data/lib/active_support/testing/isolation.rb +1 -1
  151. data/lib/active_support/testing/method_call_assertions.rb +21 -8
  152. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  153. data/lib/active_support/testing/stream.rb +1 -1
  154. data/lib/active_support/testing/strict_warnings.rb +38 -0
  155. data/lib/active_support/testing/time_helpers.rb +32 -14
  156. data/lib/active_support/time_with_zone.rb +4 -14
  157. data/lib/active_support/values/time_zone.rb +9 -7
  158. data/lib/active_support/version.rb +1 -1
  159. data/lib/active_support/xml_mini/jdom.rb +3 -10
  160. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  161. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  162. data/lib/active_support/xml_mini/rexml.rb +1 -1
  163. data/lib/active_support/xml_mini.rb +2 -2
  164. data/lib/active_support.rb +14 -3
  165. metadata +102 -15
  166. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  167. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
  168. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
  169. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  170. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
  171. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
  172. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  173. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
  174. data/lib/active_support/core_ext/uri.rb +0 -5
  175. data/lib/active_support/per_thread_registry.rb +0 -65
data/CHANGELOG.md CHANGED
@@ -1,565 +1,1095 @@
1
- ## Rails 7.0.8 (September 09, 2023) ##
1
+ ## Rails 7.1.1 (October 11, 2023) ##
2
2
 
3
- * Fix `TimeWithZone` still using deprecated `#to_s` when `ENV` or `config` to
4
- disable it are set.
3
+ * Add support for keyword arguments when delegating calls to custom loggers from `ActiveSupport::BroadcastLogger`.
5
4
 
6
- *Hartley McGuire*
5
+ *Edouard Chin*
6
+
7
+ * `NumberHelper`: handle objects responding `to_d`.
8
+
9
+ *fatkodima*
10
+
11
+ * Fix RedisCacheStore to properly set the TTL when incrementing or decrementing.
7
12
 
8
- * Fix CacheStore#write_multi when using a distributed Redis cache with a connection pool.
13
+ This bug was only impacting Redis server older than 7.0.
9
14
 
10
- Fixes [#48938](https://github.com/rails/rails/issues/48938).
15
+ *Thomas Countz*
11
16
 
12
- *Jonathan del Strother*
17
+ * Fix MemoryStore to prevent race conditions when incrementing or decrementing.
13
18
 
19
+ *Pierre Jambet*
14
20
 
15
- ## Rails 7.0.7.2 (August 22, 2023) ##
21
+
22
+ ## Rails 7.1.0 (October 05, 2023) ##
16
23
 
17
24
  * No changes.
18
25
 
19
26
 
20
- ## Rails 7.0.7.1 (August 22, 2023) ##
27
+ ## Rails 7.1.0.rc2 (October 01, 2023) ##
21
28
 
22
- * Use a temporary file for storing unencrypted files while editing
29
+ * Fix `AS::MessagePack` with `ENV["RAILS_MAX_THREADS"]`.
23
30
 
24
- [CVE-2023-38037]
31
+ *Jonathan Hefner*
25
32
 
26
33
 
27
- ## Rails 7.0.7 (August 09, 2023) ##
34
+ ## Rails 7.1.0.rc1 (September 27, 2023) ##
28
35
 
29
- * Fix `Cache::NullStore` with local caching for repeated reads.
36
+ * Add a new public API for broadcasting logs
30
37
 
31
- *fatkodima*
38
+ This feature existed for a while but was until now a private API.
39
+ Broadcasting log allows to send log message to difference sinks (STDOUT, a file ...) and
40
+ is used by default in the development environment to write logs both on STDOUT and in the
41
+ "development.log" file.
32
42
 
33
- * Fix `to_s` with no arguments not respecting custom `:default` formats
43
+ Basic usage:
34
44
 
35
- *Hartley McGuire*
45
+ ```ruby
46
+ stdout_logger = Logger.new(STDOUT)
47
+ file_logger = Logger.new("development.log")
48
+ broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger, file_logger)
36
49
 
37
- * Fix `ActiveSupport::Inflector.humanize(nil)` raising ``NoMethodError: undefined method `end_with?' for nil:NilClass``.
50
+ broadcast.info("Hello!") # The "Hello!" message is written on STDOUT and in the log file.
51
+ ```
38
52
 
39
- *James Robinson*
53
+ Adding other sink(s) to the broadcast:
40
54
 
41
- * Fix `Enumerable#sum` for `Enumerator#lazy`.
55
+ ```ruby
56
+ broadcast = ActiveSupport::BroadcastLogger.new
57
+ broadcast.broadcast_to(Logger.new(STDERR))
58
+ ```
42
59
 
43
- *fatkodima*, *Matthew Draper*, *Jonathan Hefner*
60
+ Remove a sink from the broadcast:
44
61
 
45
- * Improve error message when EventedFileUpdateChecker is used without a
46
- compatible version of the Listen gem
62
+ ```ruby
63
+ stdout_logger = Logger.new(STDOUT)
64
+ broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger)
47
65
 
48
- *Hartley McGuire*
66
+ broadcast.stop_broadcasting_to(stdout_logger)
67
+ ```
49
68
 
69
+ *Edouard Chin*
50
70
 
51
- ## Rails 7.0.6 (June 29, 2023) ##
71
+ * Fix Range#overlap? not taking empty ranges into account on Ruby < 3.3
52
72
 
53
- * Fix `EncryptedConfiguration` returning incorrect values for some `Hash`
54
- methods
73
+ *Nobuyoshi Nakada*, *Shouichi Kamiya*, *Hartley McGuire*
55
74
 
56
- *Hartley McGuire*
75
+ * Use Ruby 3.3 Range#overlap? if available
57
76
 
58
- * Fix arguments being destructed `Enumerable#many?` with block.
77
+ *Yasuo Honda*
59
78
 
60
- *Andrew Novoselac*
61
79
 
62
- * Fix humanize for strings ending with id.
80
+ ## Rails 7.1.0.beta1 (September 13, 2023) ##
63
81
 
64
- *fatkodima*
82
+ * Add `bigdecimal` as Active Support dependency that is a bundled gem candidate for Ruby 3.4.
65
83
 
84
+ `bigdecimal` 3.1.4 or higher version will be installed.
85
+ Ruby 2.7 and 3.0 users who want `bigdecimal` version 2.0.0 or 3.0.0 behavior as a default gem,
86
+ pin the `bigdecimal` version in your application Gemfile.
66
87
 
67
- ## Rails 7.0.5.1 (June 26, 2023) ##
88
+ *Koichi ITO*
68
89
 
69
- * No changes.
90
+ * Add `drb`, `mutex_m` and `base64` that are bundled gem candidates for Ruby 3.4
70
91
 
92
+ *Yasuo Honda*
71
93
 
72
- ## Rails 7.0.5 (May 24, 2023) ##
94
+ * When using cache format version >= 7.1 or a custom serializer, expired and
95
+ version-mismatched cache entries can now be detected without deserializing
96
+ their values.
73
97
 
74
- * Fixes TimeWithZone ArgumentError.
98
+ *Jonathan Hefner*
75
99
 
76
- *Niklas Häusele*
100
+ * Make all cache stores return a boolean for `#delete`
77
101
 
102
+ Previously the `RedisCacheStore#delete` would return `1` if the entry
103
+ exists and `0` otherwise. Now it returns true if the entry exists and false
104
+ otherwise, just like the other stores.
78
105
 
79
- ## Rails 7.0.4.3 (March 13, 2023) ##
106
+ The `FileStore` would return `nil` if the entry doesn't exists and returns
107
+ `false` now as well.
80
108
 
81
- * Implement SafeBuffer#bytesplice
109
+ *Petrik de Heus*
82
110
 
83
- [CVE-2023-28120]
111
+ * Active Support cache stores now support replacing the default compressor via
112
+ a `:compressor` option. The specified compressor must respond to `deflate`
113
+ and `inflate`. For example:
84
114
 
115
+ ```ruby
116
+ module MyCompressor
117
+ def self.deflate(string)
118
+ # compression logic...
119
+ end
85
120
 
86
- ## Rails 7.0.4.2 (January 24, 2023) ##
121
+ def self.inflate(compressed)
122
+ # decompression logic...
123
+ end
124
+ end
87
125
 
88
- * No changes.
126
+ config.cache_store = :redis_cache_store, { compressor: MyCompressor }
127
+ ```
89
128
 
129
+ *Jonathan Hefner*
90
130
 
91
- ## Rails 7.0.4.1 (January 17, 2023) ##
131
+ * Active Support cache stores now support a `:serializer` option. Similar to
132
+ the `:coder` option, serializers must respond to `dump` and `load`. However,
133
+ serializers are only responsible for serializing a cached value, whereas
134
+ coders are responsible for serializing the entire `ActiveSupport::Cache::Entry`
135
+ instance. Additionally, the output from serializers can be automatically
136
+ compressed, whereas coders are responsible for their own compression.
92
137
 
93
- * Avoid regex backtracking in Inflector.underscore
138
+ Specifying a serializer instead of a coder also enables performance
139
+ optimizations, including the bare string optimization introduced by cache
140
+ format version 7.1.
94
141
 
95
- [CVE-2023-22796]
142
+ The `:serializer` and `:coder` options are mutually exclusive. Specifying
143
+ both will raise an `ArgumentError`.
96
144
 
145
+ *Jonathan Hefner*
97
146
 
98
- ## Rails 7.0.4 (September 09, 2022) ##
147
+ * Fix `ActiveSupport::Inflector.humanize(nil)` raising ``NoMethodError: undefined method `end_with?' for nil:NilClass``.
99
148
 
100
- * Ensure `ActiveSupport::Testing::Isolation::Forking` closes pipes
149
+ *James Robinson*
101
150
 
102
- Previously, `Forking.run_in_isolation` opened two ends of a pipe. The fork
103
- process closed the read end, wrote to it, and then terminated (which
104
- presumably closed the file descriptors on its end). The parent process
105
- closed the write end, read from it, and returned, never closing the read
106
- end.
151
+ * Don't show secrets for `ActiveSupport::KeyGenerator#inspect`.
107
152
 
108
- This resulted in an accumulation of open file descriptors, which could
109
- cause errors if the limit is reached.
153
+ Before:
110
154
 
111
- *Sam Bostock*
155
+ ```ruby
156
+ ActiveSupport::KeyGenerator.new(secret).inspect
157
+ "#<ActiveSupport::KeyGenerator:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
158
+ ```
112
159
 
113
- * Redis cache store is now compatible with redis-rb 5.0.
160
+ After:
114
161
 
115
- *Jean Boussier*
162
+ ```ruby
163
+ ActiveSupport::KeyGenerator::Aes256Gcm(secret).inspect
164
+ "#<ActiveSupport::KeyGenerator:0x0000000104888038>"
165
+ ```
116
166
 
117
- * Fix `NoMethodError` on custom `ActiveSupport::Deprecation` behavior.
167
+ *Petrik de Heus*
118
168
 
119
- `ActiveSupport::Deprecation.behavior=` was supposed to accept any object
120
- that responds to `call`, but in fact its internal implementation assumed that
121
- this object could respond to `arity`, so it was restricted to only `Proc` objects.
169
+ * Improve error message when EventedFileUpdateChecker is used without a
170
+ compatible version of the Listen gem
122
171
 
123
- This change removes this `arity` restriction of custom behaviors.
172
+ *Hartley McGuire*
124
173
 
125
- *Ryo Nakamura*
174
+ * Add `:report` behavior for Deprecation
126
175
 
176
+ Setting `config.active_support.deprecation = :report` uses the error
177
+ reporter to report deprecation warnings to `ActiveSupport::ErrorReporter`.
127
178
 
128
- ## Rails 7.0.3.1 (July 12, 2022) ##
179
+ Deprecations are reported as handled errors, with a severity of `:warning`.
129
180
 
130
- * No changes.
181
+ Useful to report deprecations happening in production to your bug tracker.
131
182
 
183
+ *Étienne Barrié*
132
184
 
133
- ## Rails 7.0.3 (May 09, 2022) ##
185
+ * Rename `Range#overlaps?` to `#overlap?` and add alias for backwards compatibility
134
186
 
135
- * No changes.
187
+ *Christian Schmidt*
136
188
 
189
+ * Fix `EncryptedConfiguration` returning incorrect values for some `Hash`
190
+ methods
137
191
 
138
- ## Rails 7.0.2.4 (April 26, 2022) ##
192
+ *Hartley McGuire*
139
193
 
140
- * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
194
+ * Don't show secrets for `MessageEncryptor#inspect`.
141
195
 
142
- Add the method `ERB::Util.xml_name_escape` to escape dangerous characters
143
- in names of tags and names of attributes, following the specification of XML.
196
+ Before:
144
197
 
145
- *Álvaro Martín Fraguas*
198
+ ```ruby
199
+ ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
200
+ "#<ActiveSupport::MessageEncryptor:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
201
+ ```
146
202
 
147
- ## Rails 7.0.2.3 (March 08, 2022) ##
203
+ After:
148
204
 
149
- * No changes.
205
+ ```ruby
206
+ ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
207
+ "#<ActiveSupport::MessageEncryptor:0x0000000104888038>"
208
+ ```
150
209
 
210
+ *Petrik de Heus*
151
211
 
152
- ## Rails 7.0.2.2 (February 11, 2022) ##
212
+ * Don't show contents for `EncryptedConfiguration#inspect`.
153
213
 
154
- * Fix Reloader method signature to work with the new Executor signature
214
+ Before:
215
+ ```ruby
216
+ Rails.application.credentials.inspect
217
+ "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8 ... @config={:secret=>\"something secret\"} ... @key_file_contents=\"915e4ea054e011022398dc242\" ...>"
218
+ ```
155
219
 
220
+ After:
221
+ ```ruby
222
+ Rails.application.credentials.inspect
223
+ "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8>"
224
+ ```
156
225
 
157
- ## Rails 7.0.2.1 (February 11, 2022) ##
226
+ *Petrik de Heus*
158
227
 
159
- * No changes.
228
+ * `ERB::Util.html_escape_once` always returns an `html_safe` string.
160
229
 
230
+ This method previously maintained the `html_safe?` property of a string on the return
231
+ value. Because this string has been escaped, however, not marking it as `html_safe` causes
232
+ entities to be double-escaped.
161
233
 
162
- ## Rails 7.0.2 (February 08, 2022) ##
234
+ As an example, take this view snippet:
163
235
 
164
- * Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
236
+ ```html
237
+ <p><%= html_escape_once("this & that &amp; the other") %></p>
238
+ ```
165
239
 
166
- *Stephen Sugden*
240
+ Before this change, that would be double-escaped and render as:
167
241
 
168
- * Improve `File.atomic_write` error handling.
242
+ ```html
243
+ <p>this &amp;amp; that &amp;amp; the other</p>
244
+ ```
169
245
 
170
- *Daniel Pepper*
246
+ After this change, it renders correctly as:
171
247
 
248
+ ```html
249
+ <p>this &amp; that &amp; the other</p>
250
+ ```
172
251
 
173
- ## Rails 7.0.1 (January 06, 2022) ##
252
+ Fixes #48256
174
253
 
175
- * Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
254
+ *Mike Dalessio*
176
255
 
177
- [The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33),
178
- but `Class#subclasses` was kept, breaking the feature detection.
256
+ * Deprecate `SafeBuffer#clone_empty`.
179
257
 
180
- *Jean Boussier*
258
+ This method has not been used internally since Rails 4.2.0.
181
259
 
260
+ *Mike Dalessio*
182
261
 
183
- ## Rails 7.0.0 (December 15, 2021) ##
262
+ * `MessageEncryptor`, `MessageVerifier`, and `config.active_support.message_serializer`
263
+ now accept `:message_pack` and `:message_pack_allow_marshal` as serializers.
264
+ These serializers require the [`msgpack` gem](https://rubygems.org/gems/msgpack)
265
+ (>= 1.7.0).
184
266
 
185
- * Fix `ActiveSupport::Duration.build` to support negative values.
267
+ The Message Pack format can provide improved performance and smaller payload
268
+ sizes. It also supports round-tripping some Ruby types that are not supported
269
+ by JSON. For example:
186
270
 
187
- The algorithm to collect the `parts` of the `ActiveSupport::Duration`
188
- ignored the sign of the `value` and accumulated incorrect part values. This
189
- impacted `ActiveSupport::Duration#sum` (which is dependent on `parts`) but
190
- not `ActiveSupport::Duration#eql?` (which is dependent on `value`).
271
+ ```ruby
272
+ verifier = ActiveSupport::MessageVerifier.new("secret")
273
+ data = [{ a: 1 }, { b: 2 }.with_indifferent_access, 1.to_d, Time.at(0, 123)]
274
+ message = verifier.generate(data)
191
275
 
192
- *Caleb Buxton*, *Braden Staudacher*
276
+ # BEFORE with config.active_support.message_serializer = :json
277
+ verifier.verified(message)
278
+ # => [{"a"=>1}, {"b"=>2}, "1.0", "1969-12-31T18:00:00.000-06:00"]
279
+ verifier.verified(message).map(&:class)
280
+ # => [Hash, Hash, String, String]
193
281
 
282
+ # AFTER with config.active_support.message_serializer = :message_pack
283
+ verifier.verified(message)
284
+ # => [{:a=>1}, {"b"=>2}, 0.1e1, 1969-12-31 18:00:00.000123 -0600]
285
+ verifier.verified(message).map(&:class)
286
+ # => [Hash, ActiveSupport::HashWithIndifferentAccess, BigDecimal, Time]
287
+ ```
194
288
 
195
- ## Rails 7.0.0.rc3 (December 14, 2021) ##
289
+ The `:message_pack` serializer can fall back to deserializing with
290
+ `ActiveSupport::JSON` when necessary, and the `:message_pack_allow_marshal`
291
+ serializer can fall back to deserializing with `Marshal` as well as
292
+ `ActiveSupport::JSON`. Additionally, the `:marshal`, `:json`, and
293
+ `:json_allow_marshal` serializers can now fall back to deserializing with
294
+ `ActiveSupport::MessagePack` when necessary. These behaviors ensure old
295
+ messages can still be read so that migration is easier.
196
296
 
197
- * No changes.
297
+ *Jonathan Hefner*
198
298
 
299
+ * A new `7.1` cache format is available which includes an optimization for
300
+ bare string values such as view fragments.
199
301
 
200
- ## Rails 7.0.0.rc2 (December 14, 2021) ##
302
+ The `7.1` cache format is used by default for new apps, and existing apps
303
+ can enable the format by setting `config.load_defaults 7.1` or by setting
304
+ `config.active_support.cache_format_version = 7.1` in `config/application.rb`
305
+ or a `config/environments/*.rb` file.
201
306
 
202
- * No changes.
307
+ Cache entries written using the `6.1` or `7.0` cache formats can be read
308
+ when using the `7.1` format. To perform a rolling deploy of a Rails 7.1
309
+ upgrade, wherein servers that have not yet been upgraded must be able to
310
+ read caches from upgraded servers, leave the cache format unchanged on the
311
+ first deploy, then enable the `7.1` cache format on a subsequent deploy.
203
312
 
204
- ## Rails 7.0.0.rc1 (December 06, 2021) ##
313
+ *Jonathan Hefner*
205
314
 
206
- * Deprecate passing a format to `#to_s` in favor of `#to_formatted_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
207
- `BigDecimal`, `Float` and, `Integer`.
315
+ * Active Support cache stores can now use a preconfigured serializer based on
316
+ `ActiveSupport::MessagePack` via the `:serializer` option:
208
317
 
209
- *Rafael Mendonça França*
318
+ ```ruby
319
+ config.cache_store = :redis_cache_store, { serializer: :message_pack }
320
+ ```
321
+
322
+ The `:message_pack` serializer can reduce cache entry sizes and improve
323
+ performance, but requires the [`msgpack` gem](https://rubygems.org/gems/msgpack)
324
+ (>= 1.7.0).
325
+
326
+ The `:message_pack` serializer can read cache entries written by the default
327
+ serializer, and the default serializer can now read entries written by the
328
+ `:message_pack` serializer. These behaviors make it easy to migrate between
329
+ serializer without invalidating the entire cache.
210
330
 
211
- * Document `ActiveSupport::Testing::Deprecation`.
331
+ *Jonathan Hefner*
212
332
 
213
- *Sam Bostock & Sam Jordan*
333
+ * `Object#deep_dup` no longer duplicate named classes and modules.
214
334
 
215
- * Add `Pathname#existence`.
335
+ Before:
216
336
 
217
337
  ```ruby
218
- Pathname.new("file").existence&.read
338
+ hash = { class: Object, module: Kernel }
339
+ hash.deep_dup # => {:class=>#<Class:0x00000001063ffc80>, :module=>#<Module:0x00000001063ffa00>}
219
340
  ```
220
341
 
221
- *Timo Schilling*
342
+ After:
222
343
 
223
- * Remove deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
344
+ ```ruby
345
+ hash = { class: Object, module: Kernel }
346
+ hash.deep_dup # => {:class=>Object, :module=>Kernel}
347
+ ```
224
348
 
225
- *Rafael Mendonça França*
349
+ *Jean Boussier*
226
350
 
227
- * Remove deprecated support to use `Range#include?` to check the inclusion of a value in
228
- a date time range is deprecated.
351
+ * Consistently raise an `ArgumentError` if the `ActiveSupport::Cache` key is blank.
229
352
 
230
- *Rafael Mendonça França*
353
+ *Joshua Young*
231
354
 
232
- * Remove deprecated `URI.parser`.
355
+ * Deprecate usage of the singleton `ActiveSupport::Deprecation`.
233
356
 
234
- *Rafael Mendonça França*
357
+ All usage of `ActiveSupport::Deprecation` as a singleton is deprecated, the most common one being
358
+ `ActiveSupport::Deprecation.warn`. Gem authors should now create their own deprecator (`ActiveSupport::Deprecation`
359
+ object), and use it to emit deprecation warnings.
235
360
 
236
- * Remove deprecated `config.active_support.use_sha1_digests`.
361
+ Calling any of the following without specifying a deprecator argument is also deprecated:
362
+ * Module.deprecate
363
+ * deprecate_constant
364
+ * DeprecatedObjectProxy
365
+ * DeprecatedInstanceVariableProxy
366
+ * DeprecatedConstantProxy
367
+ * deprecation-related test assertions
237
368
 
238
- *Rafael Mendonça França*
369
+ Use of `ActiveSupport::Deprecation.silence` and configuration methods like `behavior=`, `disallowed_behavior=`,
370
+ `disallowed_warnings=` should now be aimed at the [application's deprecators](https://api.rubyonrails.org/classes/Rails/Application.html#method-i-deprecators).
239
371
 
240
- * Invoking `Object#with_options` without a `&block` argument returns the
241
- `ActiveSupport::OptionMerger` instance.
372
+ ```ruby
373
+ Rails.application.deprecators.silence do
374
+ # code that emits deprecation warnings
375
+ end
376
+ ```
242
377
 
243
- *Sean Doyle*
378
+ If your gem has a Railtie or Engine, it's encouraged to add your deprecator to the application's deprecators, that
379
+ way the deprecation related configuration options will apply to it as well, e.g.
380
+ `config.active_support.report_deprecations` set to `false` in the production environment will also disable your
381
+ deprecator.
244
382
 
245
- * `Rails.application.executor` hooks can now be called around every test
383
+ ```ruby
384
+ initializer "my_gem.deprecator" do |app|
385
+ app.deprecators[:my_gem] = MyGem.deprecator
386
+ end
387
+ ```
246
388
 
247
- This helps to better simulate request or job local state being reset around tests and prevents state
248
- leaking from one test to another.
389
+ *Étienne Barrié*
249
390
 
250
- However it requires the executor hooks executed in the test environment to be re-entrant.
391
+ * Add `Object#with` to set and restore public attributes around a block
251
392
 
252
- To enable this, set `config.active_support.executor_around_test_case = true` (this is the default in Rails 7).
393
+ ```ruby
394
+ client.timeout # => 5
395
+ client.with(timeout: 1) do
396
+ client.timeout # => 1
397
+ end
398
+ client.timeout # => 5
399
+ ```
253
400
 
254
401
  *Jean Boussier*
255
402
 
256
- * `ActiveSupport::DescendantsTracker` now mostly delegate to `Class#descendants` on Ruby 3.1
403
+ * Remove deprecated support to generate incorrect RFC 4122 UUIDs when providing a namespace ID that is not one of the
404
+ constants defined on `Digest::UUID`.
257
405
 
258
- Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless.
406
+ *Rafael Mendonça França*
259
407
 
260
- As a result the following methods are deprecated:
408
+ * Deprecate `config.active_support.use_rfc4122_namespaced_uuids`.
261
409
 
262
- - `ActiveSupport::DescendantsTracker.direct_descendants`
263
- - `ActiveSupport::DescendantsTracker#direct_descendants`
410
+ *Rafael Mendonça França*
264
411
 
265
- *Jean Boussier*
412
+ * Remove implicit conversion of objects into `String` by `ActiveSupport::SafeBuffer`.
266
413
 
267
- * Fix the `Digest::UUID.uuid_from_hash` behavior for namespace IDs that are different from the ones defined on `Digest::UUID`.
414
+ *Rafael Mendonça França*
268
415
 
269
- The new behavior will be enabled by setting the
270
- `config.active_support.use_rfc4122_namespaced_uuids` option to `true`
271
- and is the default for new apps.
416
+ * Remove deprecated `active_support/core_ext/range/include_time_with_zone` file.
272
417
 
273
- The old behavior is the default for upgraded apps and will output a
274
- deprecation warning every time a value that is different than one of
275
- the constants defined on the `Digest::UUID` extension is used as the
276
- namespace ID.
418
+ *Rafael Mendonça França*
277
419
 
278
- *Alex Robbin*, *Erich Soares Machado*, *Eugene Kenny*
420
+ * Deprecate `config.active_support.remove_deprecated_time_with_zone_name`.
279
421
 
280
- * `ActiveSupport::Inflector::Inflections#clear(:acronyms)` is now supported,
281
- and `inflector.clear` / `inflector.clear(:all)` also clears acronyms.
422
+ *Rafael Mendonça França*
282
423
 
283
- *Alex Ghiculescu*, *Oliver Peate*
424
+ * Remove deprecated override of `ActiveSupport::TimeWithZone.name`.
284
425
 
426
+ *Rafael Mendonça França*
285
427
 
286
- ## Rails 7.0.0.alpha2 (September 15, 2021) ##
428
+ * Deprecate `config.active_support.disable_to_s_conversion`.
287
429
 
288
- * No changes.
430
+ *Rafael Mendonça França*
289
431
 
432
+ * Remove deprecated option to passing a format to `#to_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
433
+ `BigDecimal`, `Float` and, `Integer`.
290
434
 
291
- ## Rails 7.0.0.alpha1 (September 15, 2021) ##
435
+ *Rafael Mendonça França*
292
436
 
293
- * `ActiveSupport::Dependencies` no longer installs a `const_missing` hook. Before this, you could push to the autoload paths and have constants autoloaded. This feature, known as the `classic` autoloader, has been removed.
437
+ * Remove deprecated `ActiveSupport::PerThreadRegistry`.
294
438
 
295
- *Xavier Noria*
439
+ *Rafael Mendonça França*
296
440
 
297
- * Private internal classes of `ActiveSupport::Dependencies` have been deleted, like `ActiveSupport::Dependencies::Reference`, `ActiveSupport::Dependencies::Blamable`, and others.
441
+ * Remove deprecated override of `Enumerable#sum`.
298
442
 
299
- *Xavier Noria*
443
+ *Rafael Mendonça França*
300
444
 
301
- * The private API of `ActiveSupport::Dependencies` has been deleted. That includes methods like `hook!`, `unhook!`, `depend_on`, `require_or_load`, `mechanism`, and many others.
445
+ * Deprecated initializing a `ActiveSupport::Cache::MemCacheStore` with an instance of `Dalli::Client`.
302
446
 
303
- *Xavier Noria*
447
+ Deprecate the undocumented option of providing an already-initialized instance of `Dalli::Client` to `ActiveSupport::Cache::MemCacheStore`. Such clients could be configured with unrecognized options, which could lead to unexpected behavior. Instead, provide addresses as documented.
304
448
 
305
- * Improves the performance of `ActiveSupport::NumberHelper` formatters by avoiding the use of exceptions as flow control.
449
+ *aledustet*
306
450
 
307
- *Mike Dalessio*
451
+ * Stub `Time.new()` in `TimeHelpers#travel_to`
452
+
453
+ ```ruby
454
+ travel_to Time.new(2004, 11, 24) do
455
+ # Inside the `travel_to` block `Time.new` is stubbed
456
+ assert_equal 2004, Time.new.year
457
+ end
458
+ ```
459
+
460
+ *fatkodima*
308
461
 
309
- * Removed rescue block from `ActiveSupport::Cache::RedisCacheStore#handle_exception`
462
+ * Raise `ActiveSupport::MessageEncryptor::InvalidMessage` from
463
+ `ActiveSupport::MessageEncryptor#decrypt_and_verify` regardless of cipher.
464
+ Previously, when a `MessageEncryptor` was using a non-AEAD cipher such as
465
+ AES-256-CBC, a corrupt or tampered message would raise
466
+ `ActiveSupport::MessageVerifier::InvalidSignature`. Now, all ciphers raise
467
+ the same error:
310
468
 
311
- Previously, if you provided a `error_handler` to `redis_cache_store`, any errors thrown by
312
- the error handler would be rescued and logged only. Removed the `rescue` clause from `handle_exception`
313
- to allow these to be thrown.
469
+ ```ruby
470
+ encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-gcm")
471
+ message = encryptor.encrypt_and_sign("message")
472
+ encryptor.decrypt_and_verify(message.next)
473
+ # => raises ActiveSupport::MessageEncryptor::InvalidMessage
314
474
 
315
- *Nicholas A. Stuart*
475
+ encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-cbc")
476
+ message = encryptor.encrypt_and_sign("message")
477
+ encryptor.decrypt_and_verify(message.next)
478
+ # BEFORE:
479
+ # => raises ActiveSupport::MessageVerifier::InvalidSignature
480
+ # AFTER:
481
+ # => raises ActiveSupport::MessageEncryptor::InvalidMessage
482
+ ```
316
483
 
317
- * Allow entirely opting out of deprecation warnings.
484
+ *Jonathan Hefner*
318
485
 
319
- Previously if you did `app.config.active_support.deprecation = :silence`, some work would
320
- still be done on each call to `ActiveSupport::Deprecation.warn`. In very hot paths, this could
321
- cause performance issues.
486
+ * Support `nil` original values when using `ActiveSupport::MessageVerifier#verify`.
487
+ Previously, `MessageVerifier#verify` did not work with `nil` original
488
+ values, though both `MessageVerifier#verified` and
489
+ `MessageEncryptor#decrypt_and_verify` do:
322
490
 
323
- Now, you can make `ActiveSupport::Deprecation.warn` a no-op:
491
+ ```ruby
492
+ encryptor = ActiveSupport::MessageEncryptor.new(secret)
493
+ message = encryptor.encrypt_and_sign(nil)
494
+
495
+ encryptor.decrypt_and_verify(message)
496
+ # => nil
497
+
498
+ verifier = ActiveSupport::MessageVerifier.new(secret)
499
+ message = verifier.generate(nil)
500
+
501
+ verifier.verified(message)
502
+ # => nil
503
+
504
+ verifier.verify(message)
505
+ # BEFORE:
506
+ # => raises ActiveSupport::MessageVerifier::InvalidSignature
507
+ # AFTER:
508
+ # => nil
509
+ ```
510
+
511
+ *Jonathan Hefner*
512
+
513
+ * Maintain `html_safe?` on html_safe strings when sliced with `slice`, `slice!`, or `chr` method.
514
+
515
+ Previously, `html_safe?` was only maintained when the html_safe strings were sliced
516
+ with `[]` method. Now, `slice`, `slice!`, and `chr` methods will maintain `html_safe?` like `[]` method.
324
517
 
325
518
  ```ruby
326
- config.active_support.report_deprecations = false
519
+ string = "<div>test</div>".html_safe
520
+ string.slice(0, 1).html_safe? # => true
521
+ string.slice!(0, 1).html_safe? # => true
522
+ # maintain html_safe? after the slice!
523
+ string.html_safe? # => true
524
+ string.chr.html_safe? # => true
327
525
  ```
328
526
 
329
- This is the default in production for new apps. It is the equivalent to:
527
+ *Michael Go*
528
+
529
+ * Add `Object#in?` support for open ranges.
330
530
 
331
531
  ```ruby
332
- config.active_support.deprecation = :silence
333
- config.active_support.disallowed_deprecation = :silence
532
+ assert Date.today.in?(..Date.tomorrow)
533
+ assert_not Date.today.in?(Date.tomorrow..)
334
534
  ```
335
535
 
336
- but will take a more optimised code path.
536
+ *Ignacio Galindo*
537
+
538
+ * `config.i18n.raise_on_missing_translations = true` now raises on any missing translation.
539
+
540
+ Previously it would only raise when called in a view or controller. Now it will raise
541
+ anytime `I18n.t` is provided an unrecognised key.
542
+
543
+ If you do not want this behaviour, you can customise the i18n exception handler. See the
544
+ upgrading guide or i18n guide for more information.
337
545
 
338
546
  *Alex Ghiculescu*
339
547
 
340
- * Faster tests by parallelizing only when overhead is justified by the number
341
- of them.
548
+ * `ActiveSupport::CurrentAttributes` now raises if a restricted attribute name is used.
549
+
550
+ Attributes such as `set` and `reset` cannot be used as they clash with the
551
+ `CurrentAttributes` public API.
552
+
553
+ *Alex Ghiculescu*
342
554
 
343
- Running tests in parallel adds overhead in terms of database
344
- setup and fixture loading. Now, Rails will only parallelize test executions when
345
- there are enough tests to make it worth it.
555
+ * `HashWithIndifferentAccess#transform_keys` now takes a Hash argument, just
556
+ as Ruby's `Hash#transform_keys` does.
346
557
 
347
- This threshold is 50 by default, and is configurable via config setting in
348
- your test.rb:
558
+ *Akira Matsuda*
559
+
560
+ * `delegate` now defines method with proper arity when delegating to a Class.
561
+ With this change, it defines faster method (3.5x faster with no argument).
562
+ However, in order to gain this benefit, the delegation target method has to
563
+ be defined before declaring the delegation.
349
564
 
350
565
  ```ruby
351
- config.active_support.test_parallelization_threshold = 100
566
+ # This defines 3.5 times faster method than before
567
+ class C
568
+ def self.x() end
569
+ delegate :x, to: :class
570
+ end
571
+
572
+ class C
573
+ # This works but silently falls back to old behavior because
574
+ # `delegate` cannot find the definition of `x`
575
+ delegate :x, to: :class
576
+ def self.x() end
577
+ end
352
578
  ```
353
579
 
354
- It's also configurable at the test case level:
580
+ *Akira Matsuda*
355
581
 
582
+ * `assert_difference` message now includes what changed.
583
+
584
+ This makes it easier to debug non-obvious failures.
585
+
586
+ Before:
587
+
588
+ ```
589
+ "User.count" didn't change by 32.
590
+ Expected: 1611
591
+ Actual: 1579
592
+ ```
593
+
594
+ After:
595
+
596
+ ```
597
+ "User.count" didn't change by 32, but by 0.
598
+ Expected: 1611
599
+ Actual: 1579
600
+ ```
601
+
602
+ *Alex Ghiculescu*
603
+
604
+ * Add ability to match exception messages to `assert_raises` assertion
605
+
606
+ Instead of this
356
607
  ```ruby
357
- class ActiveSupport::TestCase
358
- parallelize threshold: 100
608
+ error = assert_raises(ArgumentError) do
609
+ perform_service(param: 'exception')
359
610
  end
611
+ assert_match(/incorrect param/i, error.message)
360
612
  ```
361
613
 
362
- *Jorge Manrubia*
614
+ you can now write this
615
+ ```ruby
616
+ assert_raises(ArgumentError, match: /incorrect param/i) do
617
+ perform_service(param: 'exception')
618
+ end
619
+ ```
620
+
621
+ *fatkodima*
622
+
623
+ * Add `Rails.env.local?` shorthand for `Rails.env.development? || Rails.env.test?`.
624
+
625
+ *DHH*
363
626
 
364
- * OpenSSL constants are now used for Digest computations.
627
+ * `ActiveSupport::Testing::TimeHelpers` now accepts named `with_usec` argument
628
+ to `freeze_time`, `travel`, and `travel_to` methods. Passing true prevents
629
+ truncating the destination time with `change(usec: 0)`.
365
630
 
366
- *Dirkjan Bussink*
631
+ *KevSlashNull*, and *serprex*
367
632
 
368
- * `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method.
369
- A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
370
- and `:yday` fragments returned from `Date._iso8601`.
633
+ * `ActiveSupport::CurrentAttributes.resets` now accepts a method name
634
+
635
+ The block API is still the recommended approach, but now both APIs are supported:
371
636
 
372
637
  ```ruby
373
- twz = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].iso8601("21087")
374
- twz.to_a[0, 6] == [0, 0, 0, 28, 03, 2021]
638
+ class Current < ActiveSupport::CurrentAttributes
639
+ resets { Time.zone = nil }
640
+ resets :clear_time_zone
641
+ end
375
642
  ```
376
643
 
377
- *Steve Laing*
644
+ *Alex Ghiculescu*
645
+
646
+ * Ensure `ActiveSupport::Testing::Isolation::Forking` closes pipes
647
+
648
+ Previously, `Forking.run_in_isolation` opened two ends of a pipe. The fork
649
+ process closed the read end, wrote to it, and then terminated (which
650
+ presumably closed the file descriptors on its end). The parent process
651
+ closed the write end, read from it, and returned, never closing the read
652
+ end.
378
653
 
379
- * `Time#change` and methods that call it (e.g. `Time#advance`) will now
380
- return a `Time` with the timezone argument provided, if the caller was
381
- initialized with a timezone argument.
654
+ This resulted in an accumulation of open file descriptors, which could
655
+ cause errors if the limit is reached.
382
656
 
383
- Fixes [#42467](https://github.com/rails/rails/issues/42467).
657
+ *Sam Bostock*
384
658
 
385
- *Alex Ghiculescu*
659
+ * Fix `Time#change` and `Time#advance` for times around the end of Daylight
660
+ Saving Time.
661
+
662
+ Previously, when `Time#change` or `Time#advance` constructed a time inside
663
+ the final stretch of Daylight Saving Time (DST), the non-DST offset would
664
+ always be chosen for local times:
665
+
666
+ ```ruby
667
+ # DST ended just before 2021-11-07 2:00:00 AM in US/Eastern.
668
+ ENV["TZ"] = "US/Eastern"
669
+
670
+ time = Time.local(2021, 11, 07, 00, 59, 59) + 1
671
+ # => 2021-11-07 01:00:00 -0400
672
+ time.change(day: 07)
673
+ # => 2021-11-07 01:00:00 -0500
674
+ time.advance(seconds: 0)
675
+ # => 2021-11-07 01:00:00 -0500
676
+
677
+ time = Time.local(2021, 11, 06, 01, 00, 00)
678
+ # => 2021-11-06 01:00:00 -0400
679
+ time.change(day: 07)
680
+ # => 2021-11-07 01:00:00 -0500
681
+ time.advance(days: 1)
682
+ # => 2021-11-07 01:00:00 -0500
683
+ ```
684
+
685
+ And the DST offset would always be chosen for times with a `TimeZone`
686
+ object:
687
+
688
+ ```ruby
689
+ Time.zone = "US/Eastern"
690
+
691
+ time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
692
+ # => 2021-11-07 01:00:00 -0500
693
+ time.change(day: 07)
694
+ # => 2021-11-07 01:00:00 -0400
695
+ time.advance(seconds: 0)
696
+ # => 2021-11-07 01:00:00 -0400
697
+
698
+ time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
699
+ # => 2021-11-08 01:00:00 -0500
700
+ time.change(day: 07)
701
+ # => 2021-11-07 01:00:00 -0400
702
+ time.advance(days: -1)
703
+ # => 2021-11-07 01:00:00 -0400
704
+ ```
705
+
706
+ Now, `Time#change` and `Time#advance` will choose the offset that matches
707
+ the original time's offset when possible:
386
708
 
387
- * Allow serializing any module or class to JSON by name.
709
+ ```ruby
710
+ ENV["TZ"] = "US/Eastern"
711
+
712
+ time = Time.local(2021, 11, 07, 00, 59, 59) + 1
713
+ # => 2021-11-07 01:00:00 -0400
714
+ time.change(day: 07)
715
+ # => 2021-11-07 01:00:00 -0400
716
+ time.advance(seconds: 0)
717
+ # => 2021-11-07 01:00:00 -0400
718
+
719
+ time = Time.local(2021, 11, 06, 01, 00, 00)
720
+ # => 2021-11-06 01:00:00 -0400
721
+ time.change(day: 07)
722
+ # => 2021-11-07 01:00:00 -0400
723
+ time.advance(days: 1)
724
+ # => 2021-11-07 01:00:00 -0400
725
+
726
+ Time.zone = "US/Eastern"
727
+
728
+ time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
729
+ # => 2021-11-07 01:00:00 -0500
730
+ time.change(day: 07)
731
+ # => 2021-11-07 01:00:00 -0500
732
+ time.advance(seconds: 0)
733
+ # => 2021-11-07 01:00:00 -0500
734
+
735
+ time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
736
+ # => 2021-11-08 01:00:00 -0500
737
+ time.change(day: 07)
738
+ # => 2021-11-07 01:00:00 -0500
739
+ time.advance(days: -1)
740
+ # => 2021-11-07 01:00:00 -0500
741
+ ```
388
742
 
389
- *Tyler Rick*, *Zachary Scott*
743
+ *Kevin Hall*, *Takayoshi Nishida*, and *Jonathan Hefner*
390
744
 
391
- * Raise `ActiveSupport::EncryptedFile::MissingKeyError` when the
392
- `RAILS_MASTER_KEY` environment variable is blank (e.g. `""`).
745
+ * Fix MemoryStore to preserve entries TTL when incrementing or decrementing
393
746
 
394
- *Sunny Ripert*
747
+ This is to be more consistent with how MemCachedStore and RedisCacheStore behaves.
395
748
 
396
- * The `from:` option is added to `ActiveSupport::TestCase#assert_no_changes`.
749
+ *Jean Boussier*
397
750
 
398
- It permits asserting on the initial value that is expected not to change.
751
+ * `Rails.error.handle` and `Rails.error.record` filter now by multiple error classes.
399
752
 
400
753
  ```ruby
401
- assert_no_changes -> { Status.all_good? }, from: true do
402
- post :create, params: { status: { ok: true } }
754
+ Rails.error.handle(IOError, ArgumentError) do
755
+ 1 + '1' # raises TypeError
403
756
  end
757
+ 1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
404
758
  ```
405
759
 
406
- *George Claghorn*
760
+ *Martin Spickermann*
407
761
 
408
- * Deprecate `ActiveSupport::SafeBuffer`'s incorrect implicit conversion of objects into string.
762
+ * `Class#subclasses` and `Class#descendants` now automatically filter reloaded classes.
409
763
 
410
- Except for a few methods like `String#%`, objects must implement `#to_str`
411
- to be implicitly converted to a String in string operations. In some
412
- circumstances `ActiveSupport::SafeBuffer` was incorrectly calling the
413
- explicit conversion method (`#to_s`) on them. This behavior is now
414
- deprecated.
764
+ Previously they could return old implementations of reloadable classes that have been
765
+ dereferenced but not yet garbage collected.
766
+
767
+ They now automatically filter such classes like `DescendantTracker#subclasses` and
768
+ `DescendantTracker#descendants`.
415
769
 
416
770
  *Jean Boussier*
417
771
 
418
- * Allow nested access to keys on `Rails.application.credentials`.
772
+ * `Rails.error.report` now marks errors as reported to avoid reporting them twice.
419
773
 
420
- Previously only top level keys in `credentials.yml.enc` could be accessed with method calls. Now any key can.
774
+ In some cases, users might want to report errors explicitly with some extra context
775
+ before letting it bubble up.
421
776
 
422
- For example, given these secrets:
777
+ This also allows to safely catch and report errors outside of the execution context.
423
778
 
424
- ```yml
425
- aws:
426
- access_key_id: 123
427
- secret_access_key: 345
779
+ *Jean Boussier*
780
+
781
+ * Add `assert_error_reported` and `assert_no_error_reported`
782
+
783
+ Allows to easily asserts an error happened but was handled
784
+
785
+ ```ruby
786
+ report = assert_error_reported(IOError) do
787
+ # ...
788
+ end
789
+ assert_equal "Oops", report.error.message
790
+ assert_equal "admin", report.context[:section]
791
+ assert_equal :warning, report.severity
792
+ assert_predicate report, :handled?
428
793
  ```
429
794
 
430
- `Rails.application.credentials.aws.access_key_id` will now return the same thing as
431
- `Rails.application.credentials.aws[:access_key_id]`.
795
+ *Jean Boussier*
432
796
 
433
- *Alex Ghiculescu*
797
+ * `ActiveSupport::Deprecation` behavior callbacks can now receive the
798
+ deprecator instance as an argument. This makes it easier for such callbacks
799
+ to change their behavior based on the deprecator's state. For example,
800
+ based on the deprecator's `debug` flag.
434
801
 
435
- * Added a faster and more compact `ActiveSupport::Cache` serialization format.
802
+ 3-arity and splat-args callbacks such as the following will now be passed
803
+ the deprecator instance as their third argument:
436
804
 
437
- It can be enabled with `config.active_support.cache_format_version = 7.0` or
438
- `config.load_defaults 7.0`. Regardless of the configuration Active Support
439
- 7.0 can read cache entries serialized by Active Support 6.1 which allows to
440
- upgrade without invalidating the cache. However Rails 6.1 can't read the
441
- new format, so all readers must be upgraded before the new format is enabled.
805
+ * `->(message, callstack, deprecator) { ... }`
806
+ * `->(*args) { ... }`
807
+ * `->(message, *other_args) { ... }`
442
808
 
443
- *Jean Boussier*
809
+ 2-arity and 4-arity callbacks such as the following will continue to behave
810
+ the same as before:
444
811
 
445
- * Add `Enumerable#sole`, per `ActiveRecord::FinderMethods#sole`. Returns the
446
- sole item of the enumerable, raising if no items are found, or if more than
447
- one is.
812
+ * `->(message, callstack) { ... }`
813
+ * `->(message, callstack, deprecation_horizon, gem_name) { ... }`
814
+ * `->(message, callstack, *deprecation_details) { ... }`
448
815
 
449
- *Asherah Connor*
816
+ *Jonathan Hefner*
450
817
 
451
- * Freeze `ActiveSupport::Duration#parts` and remove writer methods.
818
+ * `ActiveSupport::Deprecation#disallowed_warnings` now affects the instance on
819
+ which it is configured.
452
820
 
453
- Durations are meant to be value objects and should not be mutated.
821
+ This means that individual `ActiveSupport::Deprecation` instances can be
822
+ configured with their own disallowed warnings, and the global
823
+ `ActiveSupport::Deprecation.disallowed_warnings` now only affects the global
824
+ `ActiveSupport::Deprecation.warn`.
454
825
 
455
- *Andrew White*
826
+ **Before**
456
827
 
457
- * Fix `ActiveSupport::TimeZone#utc_to_local` with fractional seconds.
828
+ ```ruby
829
+ ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
830
+ deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
831
+ deprecator.disallowed_warnings = ["bar"]
832
+
833
+ ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
834
+ ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
835
+ deprecator.warn("foo") # => raise ActiveSupport::DeprecationException
836
+ deprecator.warn("bar") # => print "DEPRECATION WARNING: bar"
837
+ ```
458
838
 
459
- When `utc_to_local_returns_utc_offset_times` is false and the time
460
- instance had fractional seconds the new UTC time instance was out by
461
- a factor of 1,000,000 as the `Time.utc` constructor takes a usec
462
- value and not a fractional second value.
839
+ **After**
463
840
 
464
- *Andrew White*
841
+ ```ruby
842
+ ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
843
+ deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
844
+ deprecator.disallowed_warnings = ["bar"]
845
+
846
+ ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
847
+ ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
848
+ deprecator.warn("foo") # => print "DEPRECATION WARNING: foo"
849
+ deprecator.warn("bar") # => raise ActiveSupport::DeprecationException
850
+ ```
851
+
852
+ Note that global `ActiveSupport::Deprecation` methods such as `ActiveSupport::Deprecation.warn`
853
+ and `ActiveSupport::Deprecation.disallowed_warnings` have been deprecated.
854
+
855
+ *Jonathan Hefner*
465
856
 
466
- * Add `expires_at` argument to `ActiveSupport::Cache` `write` and `fetch` to set a cache entry TTL as an absolute time.
857
+ * Add italic and underline support to `ActiveSupport::LogSubscriber#color`
858
+
859
+ Previously, only bold text was supported via a positional argument.
860
+ This allows for bold, italic, and underline options to be specified
861
+ for colored logs.
467
862
 
468
863
  ```ruby
469
- Rails.cache.write(key, value, expires_at: Time.now.at_end_of_hour)
864
+ info color("Hello world!", :red, bold: true, underline: true)
470
865
  ```
471
866
 
867
+ *Gannon McGibbon*
868
+
869
+ * Add `String#downcase_first` method.
870
+
871
+ This method is the corollary of `String#upcase_first`.
872
+
873
+ *Mark Schneider*
874
+
875
+ * `thread_mattr_accessor` will call `.dup.freeze` on non-frozen default values.
876
+
877
+ This provides a basic level of protection against different threads trying
878
+ to mutate a shared default object.
879
+
880
+ *Jonathan Hefner*
881
+
882
+ * Add `raise_on_invalid_cache_expiration_time` config to `ActiveSupport::Cache::Store`
883
+
884
+ Specifies if an `ArgumentError` should be raised if `Rails.cache` `fetch` or
885
+ `write` are given an invalid `expires_at` or `expires_in` time.
886
+
887
+ Options are `true`, and `false`. If `false`, the exception will be reported
888
+ as `handled` and logged instead. Defaults to `true` if `config.load_defaults >= 7.1`.
889
+
890
+ *Trevor Turk*
891
+
892
+ * `ActiveSupport::Cache::Store#fetch` now passes an options accessor to the block.
893
+
894
+ It makes possible to override cache options:
895
+
896
+ Rails.cache.fetch("3rd-party-token") do |name, options|
897
+ token = fetch_token_from_remote
898
+ # set cache's TTL to match token's TTL
899
+ options.expires_in = token.expires_in
900
+ token
901
+ end
902
+
903
+ *Andrii Gladkyi*, *Jean Boussier*
904
+
905
+ * `default` option of `thread_mattr_accessor` now applies through inheritance and
906
+ also across new threads.
907
+
908
+ Previously, the `default` value provided was set only at the moment of defining
909
+ the attribute writer, which would cause the attribute to be uninitialized in
910
+ descendants and in other threads.
911
+
912
+ Fixes #43312.
913
+
914
+ *Thierry Deo*
915
+
916
+ * Redis cache store is now compatible with redis-rb 5.0.
917
+
472
918
  *Jean Boussier*
473
919
 
474
- * Deprecate `ActiveSupport::TimeWithZone.name` so that from Rails 7.1 it will use the default implementation.
920
+ * Add `skip_nil:` support to `ActiveSupport::Cache::Store#fetch_multi`.
475
921
 
476
- *Andrew White*
922
+ *Daniel Alfaro*
477
923
 
478
- * Deprecates Rails custom `Enumerable#sum` and `Array#sum` in favor of Ruby's native implementation which
479
- is considerably faster.
924
+ * Add `quarter` method to date/time
480
925
 
481
- Ruby requires an initializer for non-numeric type as per examples below:
926
+ *Matt Swanson*
482
927
 
483
- ```ruby
484
- %w[foo bar].sum('')
485
- # instead of %w[foo bar].sum
928
+ * Fix `NoMethodError` on custom `ActiveSupport::Deprecation` behavior.
486
929
 
487
- [[1, 2], [3, 4, 5]].sum([])
488
- # instead of [[1, 2], [3, 4, 5]].sum
489
- ```
930
+ `ActiveSupport::Deprecation.behavior=` was supposed to accept any object
931
+ that responds to `call`, but in fact its internal implementation assumed that
932
+ this object could respond to `arity`, so it was restricted to only `Proc` objects.
490
933
 
491
- *Alberto Mota*
934
+ This change removes this `arity` restriction of custom behaviors.
492
935
 
493
- * Tests parallelization is now disabled when running individual files to prevent the setup overhead.
936
+ *Ryo Nakamura*
494
937
 
495
- It can still be enforced if the environment variable `PARALLEL_WORKERS` is present and set to a value greater than 1.
938
+ * Support `:url_safe` option for `MessageEncryptor`.
496
939
 
497
- *Ricardo Díaz*
940
+ The `MessageEncryptor` constructor now accepts a `:url_safe` option, similar
941
+ to the `MessageVerifier` constructor. When enabled, this option ensures
942
+ that messages use a URL-safe encoding.
498
943
 
499
- * Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`.
944
+ *Jonathan Hefner*
500
945
 
501
- *Marcin Kołodziej*
946
+ * Add `url_safe` option to `ActiveSupport::MessageVerifier` initializer
502
947
 
503
- * Add `Enumerable#maximum` and `Enumerable#minimum` to easily calculate the maximum or minimum from extracted
504
- elements of an enumerable.
948
+ `ActiveSupport::MessageVerifier.new` now takes optional `url_safe` argument.
949
+ It can generate URL-safe strings by passing `url_safe: true`.
505
950
 
506
951
  ```ruby
507
- payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
508
-
509
- payments.minimum(:price) # => 5
510
- payments.maximum(:price) # => 15
952
+ verifier = ActiveSupport::MessageVerifier.new(url_safe: true)
953
+ message = verifier.generate(data) # => URL-safe string
511
954
  ```
512
955
 
513
- This also allows passing enumerables to `fresh_when` and `stale?` in Action Controller.
514
- See PR [#41404](https://github.com/rails/rails/pull/41404) for an example.
956
+ This option is `false` by default to be backwards compatible.
957
+
958
+ *Shouichi Kamiya*
515
959
 
516
- *Ayrton De Craene*
960
+ * Enable connection pooling by default for `MemCacheStore` and `RedisCacheStore`.
517
961
 
518
- * `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument.
962
+ If you want to disable connection pooling, set `:pool` option to `false` when configuring the cache store:
519
963
 
520
964
  ```ruby
521
- config.cache_store = :mem_cache_store, nil
965
+ config.cache_store = :mem_cache_store, "cache.example.com", pool: false
966
+ ```
522
967
 
523
- # is now equivalent to
968
+ *fatkodima*
524
969
 
525
- config.cache_store = :mem_cache_store
970
+ * Add `force:` support to `ActiveSupport::Cache::Store#fetch_multi`.
526
971
 
527
- # and is also equivalent to
972
+ *fatkodima*
528
973
 
529
- config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
974
+ * Deprecated `:pool_size` and `:pool_timeout` options for configuring connection pooling in cache stores.
530
975
 
531
- # which is the fallback behavior of Dalli
976
+ Use `pool: true` to enable pooling with default settings:
977
+
978
+ ```ruby
979
+ config.cache_store = :redis_cache_store, pool: true
532
980
  ```
533
981
 
534
- This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted.
982
+ Or pass individual options via `:pool` option:
535
983
 
536
- *Michael Overmeyer*
984
+ ```ruby
985
+ config.cache_store = :redis_cache_store, pool: { size: 10, timeout: 2 }
986
+ ```
537
987
 
538
- * Add `Enumerable#in_order_of` to put an Enumerable in a certain order by a key.
988
+ *fatkodima*
539
989
 
540
- *DHH*
990
+ * Allow #increment and #decrement methods of `ActiveSupport::Cache::Store`
991
+ subclasses to set new values.
541
992
 
542
- * `ActiveSupport::Inflector.camelize` behaves expected when provided a symbol `:upper` or `:lower` argument. Matches
543
- `String#camelize` behavior.
993
+ Previously incrementing or decrementing an unset key would fail and return
994
+ nil. A default will now be assumed and the key will be created.
544
995
 
545
- *Alex Ghiculescu*
996
+ *Andrej Blagojević*, *Eugene Kenny*
997
+
998
+ * Add `skip_nil:` support to `RedisCacheStore`
999
+
1000
+ *Joey Paris*
1001
+
1002
+ * `ActiveSupport::Cache::MemoryStore#write(name, val, unless_exist:true)` now
1003
+ correctly writes expired keys.
1004
+
1005
+ *Alan Savage*
1006
+
1007
+ * `ActiveSupport::ErrorReporter` now accepts and forward a `source:` parameter.
1008
+
1009
+ This allow libraries to signal the origin of the errors, and reporters
1010
+ to easily ignore some sources.
1011
+
1012
+ *Jean Boussier*
546
1013
 
547
- * Raises an `ArgumentError` when the first argument of `ActiveSupport::Notification.subscribe` is
548
- invalid.
1014
+ * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
1015
+
1016
+ Add the method `ERB::Util.xml_name_escape` to escape dangerous characters
1017
+ in names of tags and names of attributes, following the specification of XML.
1018
+
1019
+ *Álvaro Martín Fraguas*
1020
+
1021
+ * Respect `ActiveSupport::Logger.new`'s `:formatter` keyword argument
1022
+
1023
+ The stdlib `Logger::new` allows passing a `:formatter` keyword argument to
1024
+ set the logger's formatter. Previously `ActiveSupport::Logger.new` ignored
1025
+ that argument by always setting the formatter to an instance of
1026
+ `ActiveSupport::Logger::SimpleFormatter`.
1027
+
1028
+ *Steven Harman*
1029
+
1030
+ * Deprecate preserving the pre-Ruby 2.4 behavior of `to_time`
1031
+
1032
+ With Ruby 2.4+ the default for +to_time+ changed from converting to the
1033
+ local system time to preserving the offset of the receiver. At the time Rails
1034
+ supported older versions of Ruby so a compatibility layer was added to assist
1035
+ in the migration process. From Rails 5.0 new applications have defaulted to
1036
+ the Ruby 2.4+ behavior and since Rails 7.0 now only supports Ruby 2.7+
1037
+ this compatibility layer can be safely removed.
1038
+
1039
+ To minimize any noise generated the deprecation warning only appears when the
1040
+ setting is configured to `false` as that is the only scenario where the
1041
+ removal of the compatibility layer has any effect.
1042
+
1043
+ *Andrew White*
1044
+
1045
+ * `Pathname.blank?` only returns true for `Pathname.new("")`
1046
+
1047
+ Previously it would end up calling `Pathname#empty?` which returned true
1048
+ if the path existed and was an empty directory or file.
1049
+
1050
+ That behavior was unlikely to be expected.
1051
+
1052
+ *Jean Boussier*
1053
+
1054
+ * Deprecate `Notification::Event`'s `#children` and `#parent_of?`
1055
+
1056
+ *John Hawthorn*
1057
+
1058
+ * Change the default serializer of `ActiveSupport::MessageVerifier` from
1059
+ `Marshal` to `ActiveSupport::JSON` when using `config.load_defaults 7.1`.
1060
+
1061
+ Messages serialized with `Marshal` can still be read, but new messages will
1062
+ be serialized with `ActiveSupport::JSON`. For more information, see
1063
+ https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.
1064
+
1065
+ *Saba Kiaei*, *David Buckley*, and *Jonathan Hefner*
1066
+
1067
+ * Change the default serializer of `ActiveSupport::MessageEncryptor` from
1068
+ `Marshal` to `ActiveSupport::JSON` when using `config.load_defaults 7.1`.
1069
+
1070
+ Messages serialized with `Marshal` can still be read, but new messages will
1071
+ be serialized with `ActiveSupport::JSON`. For more information, see
1072
+ https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.
1073
+
1074
+ *Zack Deveau*, *Martin Gingras*, and *Jonathan Hefner*
549
1075
 
550
- *Vipul A M*
1076
+ * Add `ActiveSupport::TestCase#stub_const` to stub a constant for the duration of a yield.
551
1077
 
552
- * `HashWithIndifferentAccess#deep_transform_keys` now returns a `HashWithIndifferentAccess` instead of a `Hash`.
1078
+ *DHH*
553
1079
 
554
- *Nathaniel Woodthorpe*
1080
+ * Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
555
1081
 
556
- * Consume dalli’s `cache_nils` configuration as `ActiveSupport::Cache`'s `skip_nil` when using `MemCacheStore`.
1082
+ *Stephen Sugden*
557
1083
 
558
- *Ritikesh G*
1084
+ * Improve `File.atomic_write` error handling
559
1085
 
560
- * Add `RedisCacheStore#stats` method similar to `MemCacheStore#stats`. Calls `redis#info` internally.
1086
+ *Daniel Pepper*
561
1087
 
562
- *Ritikesh G*
1088
+ * Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
563
1089
 
1090
+ [The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33),
1091
+ but `Class#subclasses` was kept, breaking the feature detection.
1092
+
1093
+ *Jean Boussier*
564
1094
 
565
- Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activesupport/CHANGELOG.md) for previous changes.
1095
+ Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activesupport/CHANGELOG.md) for previous changes.