activesupport 7.0.7.1 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +832 -283
  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 +136 -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 +4 -4
  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 +6 -42
  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 +103 -16
  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 -37
  168. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -33
  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 -33
  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 -33
  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,546 +1,1095 @@
1
- ## Rails 7.0.7.1 (August 22, 2023) ##
1
+ ## Rails 7.1.1 (October 11, 2023) ##
2
2
 
3
- * Use a temporary file for storing unencrypted files while editing
3
+ * Add support for keyword arguments when delegating calls to custom loggers from `ActiveSupport::BroadcastLogger`.
4
4
 
5
- [CVE-2023-38037]
5
+ *Edouard Chin*
6
6
 
7
+ * `NumberHelper`: handle objects responding `to_d`.
7
8
 
8
- ## Rails 7.0.7 (August 09, 2023) ##
9
+ *fatkodima*
9
10
 
10
- * Fix `Cache::NullStore` with local caching for repeated reads.
11
+ * Fix RedisCacheStore to properly set the TTL when incrementing or decrementing.
11
12
 
12
- *fatkodima*
13
+ This bug was only impacting Redis server older than 7.0.
13
14
 
14
- * Fix `to_s` with no arguments not respecting custom `:default` formats
15
+ *Thomas Countz*
15
16
 
16
- *Hartley McGuire*
17
+ * Fix MemoryStore to prevent race conditions when incrementing or decrementing.
17
18
 
18
- * Fix `ActiveSupport::Inflector.humanize(nil)` raising ``NoMethodError: undefined method `end_with?' for nil:NilClass``.
19
+ *Pierre Jambet*
19
20
 
20
- *James Robinson*
21
21
 
22
- * Fix `Enumerable#sum` for `Enumerator#lazy`.
22
+ ## Rails 7.1.0 (October 05, 2023) ##
23
23
 
24
- *fatkodima*, *Matthew Draper*, *Jonathan Hefner*
24
+ * No changes.
25
25
 
26
- * Improve error message when EventedFileUpdateChecker is used without a
27
- compatible version of the Listen gem
28
26
 
29
- *Hartley McGuire*
27
+ ## Rails 7.1.0.rc2 (October 01, 2023) ##
30
28
 
29
+ * Fix `AS::MessagePack` with `ENV["RAILS_MAX_THREADS"]`.
31
30
 
32
- ## Rails 7.0.6 (June 29, 2023) ##
31
+ *Jonathan Hefner*
33
32
 
34
- * Fix `EncryptedConfiguration` returning incorrect values for some `Hash`
35
- methods
36
33
 
37
- *Hartley McGuire*
34
+ ## Rails 7.1.0.rc1 (September 27, 2023) ##
38
35
 
39
- * Fix arguments being destructed `Enumerable#many?` with block.
36
+ * Add a new public API for broadcasting logs
40
37
 
41
- *Andrew Novoselac*
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.
42
42
 
43
- * Fix humanize for strings ending with id.
43
+ Basic usage:
44
44
 
45
- *fatkodima*
45
+ ```ruby
46
+ stdout_logger = Logger.new(STDOUT)
47
+ file_logger = Logger.new("development.log")
48
+ broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger, file_logger)
46
49
 
50
+ broadcast.info("Hello!") # The "Hello!" message is written on STDOUT and in the log file.
51
+ ```
47
52
 
48
- ## Rails 7.0.5.1 (June 26, 2023) ##
53
+ Adding other sink(s) to the broadcast:
49
54
 
50
- * No changes.
55
+ ```ruby
56
+ broadcast = ActiveSupport::BroadcastLogger.new
57
+ broadcast.broadcast_to(Logger.new(STDERR))
58
+ ```
51
59
 
60
+ Remove a sink from the broadcast:
52
61
 
53
- ## Rails 7.0.5 (May 24, 2023) ##
62
+ ```ruby
63
+ stdout_logger = Logger.new(STDOUT)
64
+ broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger)
54
65
 
55
- * Fixes TimeWithZone ArgumentError.
66
+ broadcast.stop_broadcasting_to(stdout_logger)
67
+ ```
56
68
 
57
- *Niklas Häusele*
69
+ *Edouard Chin*
58
70
 
71
+ * Fix Range#overlap? not taking empty ranges into account on Ruby < 3.3
59
72
 
60
- ## Rails 7.0.4.3 (March 13, 2023) ##
73
+ *Nobuyoshi Nakada*, *Shouichi Kamiya*, *Hartley McGuire*
61
74
 
62
- * Implement SafeBuffer#bytesplice
75
+ * Use Ruby 3.3 Range#overlap? if available
63
76
 
64
- [CVE-2023-28120]
77
+ *Yasuo Honda*
65
78
 
66
79
 
67
- ## Rails 7.0.4.2 (January 24, 2023) ##
80
+ ## Rails 7.1.0.beta1 (September 13, 2023) ##
68
81
 
69
- * No changes.
82
+ * Add `bigdecimal` as Active Support dependency that is a bundled gem candidate for Ruby 3.4.
70
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.
71
87
 
72
- ## Rails 7.0.4.1 (January 17, 2023) ##
88
+ *Koichi ITO*
73
89
 
74
- * Avoid regex backtracking in Inflector.underscore
90
+ * Add `drb`, `mutex_m` and `base64` that are bundled gem candidates for Ruby 3.4
75
91
 
76
- [CVE-2023-22796]
92
+ *Yasuo Honda*
77
93
 
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.
78
97
 
79
- ## Rails 7.0.4 (September 09, 2022) ##
98
+ *Jonathan Hefner*
80
99
 
81
- * Ensure `ActiveSupport::Testing::Isolation::Forking` closes pipes
100
+ * Make all cache stores return a boolean for `#delete`
82
101
 
83
- Previously, `Forking.run_in_isolation` opened two ends of a pipe. The fork
84
- process closed the read end, wrote to it, and then terminated (which
85
- presumably closed the file descriptors on its end). The parent process
86
- closed the write end, read from it, and returned, never closing the read
87
- end.
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.
88
105
 
89
- This resulted in an accumulation of open file descriptors, which could
90
- cause errors if the limit is reached.
106
+ The `FileStore` would return `nil` if the entry doesn't exists and returns
107
+ `false` now as well.
91
108
 
92
- *Sam Bostock*
109
+ *Petrik de Heus*
93
110
 
94
- * Redis cache store is now compatible with redis-rb 5.0.
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:
95
114
 
96
- *Jean Boussier*
115
+ ```ruby
116
+ module MyCompressor
117
+ def self.deflate(string)
118
+ # compression logic...
119
+ end
97
120
 
98
- * Fix `NoMethodError` on custom `ActiveSupport::Deprecation` behavior.
121
+ def self.inflate(compressed)
122
+ # decompression logic...
123
+ end
124
+ end
99
125
 
100
- `ActiveSupport::Deprecation.behavior=` was supposed to accept any object
101
- that responds to `call`, but in fact its internal implementation assumed that
102
- this object could respond to `arity`, so it was restricted to only `Proc` objects.
126
+ config.cache_store = :redis_cache_store, { compressor: MyCompressor }
127
+ ```
103
128
 
104
- This change removes this `arity` restriction of custom behaviors.
129
+ *Jonathan Hefner*
105
130
 
106
- *Ryo Nakamura*
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.
107
137
 
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.
108
141
 
109
- ## Rails 7.0.3.1 (July 12, 2022) ##
142
+ The `:serializer` and `:coder` options are mutually exclusive. Specifying
143
+ both will raise an `ArgumentError`.
110
144
 
111
- * No changes.
145
+ *Jonathan Hefner*
112
146
 
147
+ * Fix `ActiveSupport::Inflector.humanize(nil)` raising ``NoMethodError: undefined method `end_with?' for nil:NilClass``.
113
148
 
114
- ## Rails 7.0.3 (May 09, 2022) ##
149
+ *James Robinson*
115
150
 
116
- * No changes.
151
+ * Don't show secrets for `ActiveSupport::KeyGenerator#inspect`.
117
152
 
153
+ Before:
118
154
 
119
- ## Rails 7.0.2.4 (April 26, 2022) ##
155
+ ```ruby
156
+ ActiveSupport::KeyGenerator.new(secret).inspect
157
+ "#<ActiveSupport::KeyGenerator:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
158
+ ```
120
159
 
121
- * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
160
+ After:
122
161
 
123
- Add the method `ERB::Util.xml_name_escape` to escape dangerous characters
124
- in names of tags and names of attributes, following the specification of XML.
162
+ ```ruby
163
+ ActiveSupport::KeyGenerator::Aes256Gcm(secret).inspect
164
+ "#<ActiveSupport::KeyGenerator:0x0000000104888038>"
165
+ ```
125
166
 
126
- *Álvaro Martín Fraguas*
167
+ *Petrik de Heus*
127
168
 
128
- ## Rails 7.0.2.3 (March 08, 2022) ##
169
+ * Improve error message when EventedFileUpdateChecker is used without a
170
+ compatible version of the Listen gem
129
171
 
130
- * No changes.
172
+ *Hartley McGuire*
131
173
 
174
+ * Add `:report` behavior for Deprecation
132
175
 
133
- ## Rails 7.0.2.2 (February 11, 2022) ##
176
+ Setting `config.active_support.deprecation = :report` uses the error
177
+ reporter to report deprecation warnings to `ActiveSupport::ErrorReporter`.
134
178
 
135
- * Fix Reloader method signature to work with the new Executor signature
179
+ Deprecations are reported as handled errors, with a severity of `:warning`.
136
180
 
181
+ Useful to report deprecations happening in production to your bug tracker.
137
182
 
138
- ## Rails 7.0.2.1 (February 11, 2022) ##
183
+ *Étienne Barrié*
139
184
 
140
- * No changes.
185
+ * Rename `Range#overlaps?` to `#overlap?` and add alias for backwards compatibility
141
186
 
187
+ *Christian Schmidt*
142
188
 
143
- ## Rails 7.0.2 (February 08, 2022) ##
189
+ * Fix `EncryptedConfiguration` returning incorrect values for some `Hash`
190
+ methods
144
191
 
145
- * Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
192
+ *Hartley McGuire*
146
193
 
147
- *Stephen Sugden*
194
+ * Don't show secrets for `MessageEncryptor#inspect`.
148
195
 
149
- * Improve `File.atomic_write` error handling.
196
+ Before:
150
197
 
151
- *Daniel Pepper*
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
+ ```
152
202
 
203
+ After:
153
204
 
154
- ## Rails 7.0.1 (January 06, 2022) ##
205
+ ```ruby
206
+ ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
207
+ "#<ActiveSupport::MessageEncryptor:0x0000000104888038>"
208
+ ```
155
209
 
156
- * Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
210
+ *Petrik de Heus*
157
211
 
158
- [The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33),
159
- but `Class#subclasses` was kept, breaking the feature detection.
212
+ * Don't show contents for `EncryptedConfiguration#inspect`.
160
213
 
161
- *Jean Boussier*
214
+ Before:
215
+ ```ruby
216
+ Rails.application.credentials.inspect
217
+ "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8 ... @config={:secret=>\"something secret\"} ... @key_file_contents=\"915e4ea054e011022398dc242\" ...>"
218
+ ```
162
219
 
220
+ After:
221
+ ```ruby
222
+ Rails.application.credentials.inspect
223
+ "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8>"
224
+ ```
163
225
 
164
- ## Rails 7.0.0 (December 15, 2021) ##
226
+ *Petrik de Heus*
165
227
 
166
- * Fix `ActiveSupport::Duration.build` to support negative values.
228
+ * `ERB::Util.html_escape_once` always returns an `html_safe` string.
167
229
 
168
- The algorithm to collect the `parts` of the `ActiveSupport::Duration`
169
- ignored the sign of the `value` and accumulated incorrect part values. This
170
- impacted `ActiveSupport::Duration#sum` (which is dependent on `parts`) but
171
- not `ActiveSupport::Duration#eql?` (which is dependent on `value`).
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.
172
233
 
173
- *Caleb Buxton*, *Braden Staudacher*
234
+ As an example, take this view snippet:
174
235
 
236
+ ```html
237
+ <p><%= html_escape_once("this & that &amp; the other") %></p>
238
+ ```
175
239
 
176
- ## Rails 7.0.0.rc3 (December 14, 2021) ##
240
+ Before this change, that would be double-escaped and render as:
177
241
 
178
- * No changes.
242
+ ```html
243
+ <p>this &amp;amp; that &amp;amp; the other</p>
244
+ ```
179
245
 
246
+ After this change, it renders correctly as:
180
247
 
181
- ## Rails 7.0.0.rc2 (December 14, 2021) ##
248
+ ```html
249
+ <p>this &amp; that &amp; the other</p>
250
+ ```
182
251
 
183
- * No changes.
252
+ Fixes #48256
184
253
 
185
- ## Rails 7.0.0.rc1 (December 06, 2021) ##
254
+ *Mike Dalessio*
186
255
 
187
- * Deprecate passing a format to `#to_s` in favor of `#to_formatted_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
188
- `BigDecimal`, `Float` and, `Integer`.
256
+ * Deprecate `SafeBuffer#clone_empty`.
189
257
 
190
- *Rafael Mendonça França*
258
+ This method has not been used internally since Rails 4.2.0.
259
+
260
+ *Mike Dalessio*
261
+
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).
266
+
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:
270
+
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)
275
+
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]
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
+ ```
288
+
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.
296
+
297
+ *Jonathan Hefner*
298
+
299
+ * A new `7.1` cache format is available which includes an optimization for
300
+ bare string values such as view fragments.
301
+
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.
306
+
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.
312
+
313
+ *Jonathan Hefner*
314
+
315
+ * Active Support cache stores can now use a preconfigured serializer based on
316
+ `ActiveSupport::MessagePack` via the `:serializer` option:
317
+
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).
191
325
 
192
- * Document `ActiveSupport::Testing::Deprecation`.
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.
193
330
 
194
- *Sam Bostock & Sam Jordan*
331
+ *Jonathan Hefner*
195
332
 
196
- * Add `Pathname#existence`.
333
+ * `Object#deep_dup` no longer duplicate named classes and modules.
334
+
335
+ Before:
197
336
 
198
337
  ```ruby
199
- Pathname.new("file").existence&.read
338
+ hash = { class: Object, module: Kernel }
339
+ hash.deep_dup # => {:class=>#<Class:0x00000001063ffc80>, :module=>#<Module:0x00000001063ffa00>}
200
340
  ```
201
341
 
202
- *Timo Schilling*
342
+ After:
203
343
 
204
- * 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
+ ```
205
348
 
206
- *Rafael Mendonça França*
349
+ *Jean Boussier*
207
350
 
208
- * Remove deprecated support to use `Range#include?` to check the inclusion of a value in
209
- a date time range is deprecated.
351
+ * Consistently raise an `ArgumentError` if the `ActiveSupport::Cache` key is blank.
210
352
 
211
- *Rafael Mendonça França*
353
+ *Joshua Young*
212
354
 
213
- * Remove deprecated `URI.parser`.
355
+ * Deprecate usage of the singleton `ActiveSupport::Deprecation`.
214
356
 
215
- *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.
216
360
 
217
- * 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
218
368
 
219
- *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).
220
371
 
221
- * Invoking `Object#with_options` without a `&block` argument returns the
222
- `ActiveSupport::OptionMerger` instance.
372
+ ```ruby
373
+ Rails.application.deprecators.silence do
374
+ # code that emits deprecation warnings
375
+ end
376
+ ```
223
377
 
224
- *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.
225
382
 
226
- * `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
+ ```
227
388
 
228
- This helps to better simulate request or job local state being reset around tests and prevents state
229
- leaking from one test to another.
389
+ *Étienne Barrié*
230
390
 
231
- 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
232
392
 
233
- 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
+ ```
234
400
 
235
401
  *Jean Boussier*
236
402
 
237
- * `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`.
238
405
 
239
- Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless.
406
+ *Rafael Mendonça França*
240
407
 
241
- As a result the following methods are deprecated:
408
+ * Deprecate `config.active_support.use_rfc4122_namespaced_uuids`.
242
409
 
243
- - `ActiveSupport::DescendantsTracker.direct_descendants`
244
- - `ActiveSupport::DescendantsTracker#direct_descendants`
410
+ *Rafael Mendonça França*
245
411
 
246
- *Jean Boussier*
412
+ * Remove implicit conversion of objects into `String` by `ActiveSupport::SafeBuffer`.
247
413
 
248
- * 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*
249
415
 
250
- The new behavior will be enabled by setting the
251
- `config.active_support.use_rfc4122_namespaced_uuids` option to `true`
252
- and is the default for new apps.
416
+ * Remove deprecated `active_support/core_ext/range/include_time_with_zone` file.
253
417
 
254
- The old behavior is the default for upgraded apps and will output a
255
- deprecation warning every time a value that is different than one of
256
- the constants defined on the `Digest::UUID` extension is used as the
257
- namespace ID.
418
+ *Rafael Mendonça França*
258
419
 
259
- *Alex Robbin*, *Erich Soares Machado*, *Eugene Kenny*
420
+ * Deprecate `config.active_support.remove_deprecated_time_with_zone_name`.
260
421
 
261
- * `ActiveSupport::Inflector::Inflections#clear(:acronyms)` is now supported,
262
- and `inflector.clear` / `inflector.clear(:all)` also clears acronyms.
422
+ *Rafael Mendonça França*
263
423
 
264
- *Alex Ghiculescu*, *Oliver Peate*
424
+ * Remove deprecated override of `ActiveSupport::TimeWithZone.name`.
265
425
 
426
+ *Rafael Mendonça França*
266
427
 
267
- ## Rails 7.0.0.alpha2 (September 15, 2021) ##
428
+ * Deprecate `config.active_support.disable_to_s_conversion`.
268
429
 
269
- * No changes.
430
+ *Rafael Mendonça França*
270
431
 
432
+ * Remove deprecated option to passing a format to `#to_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
433
+ `BigDecimal`, `Float` and, `Integer`.
271
434
 
272
- ## Rails 7.0.0.alpha1 (September 15, 2021) ##
435
+ *Rafael Mendonça França*
273
436
 
274
- * `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`.
275
438
 
276
- *Xavier Noria*
439
+ *Rafael Mendonça França*
277
440
 
278
- * 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`.
279
442
 
280
- *Xavier Noria*
443
+ *Rafael Mendonça França*
281
444
 
282
- * 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`.
283
446
 
284
- *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.
285
448
 
286
- * Improves the performance of `ActiveSupport::NumberHelper` formatters by avoiding the use of exceptions as flow control.
449
+ *aledustet*
287
450
 
288
- *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*
461
+
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:
468
+
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
474
+
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
+ ```
483
+
484
+ *Jonathan Hefner*
289
485
 
290
- * Removed rescue block from `ActiveSupport::Cache::RedisCacheStore#handle_exception`
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:
291
490
 
292
- Previously, if you provided a `error_handler` to `redis_cache_store`, any errors thrown by
293
- the error handler would be rescued and logged only. Removed the `rescue` clause from `handle_exception`
294
- to allow these to be thrown.
491
+ ```ruby
492
+ encryptor = ActiveSupport::MessageEncryptor.new(secret)
493
+ message = encryptor.encrypt_and_sign(nil)
295
494
 
296
- *Nicholas A. Stuart*
495
+ encryptor.decrypt_and_verify(message)
496
+ # => nil
297
497
 
298
- * Allow entirely opting out of deprecation warnings.
498
+ verifier = ActiveSupport::MessageVerifier.new(secret)
499
+ message = verifier.generate(nil)
299
500
 
300
- Previously if you did `app.config.active_support.deprecation = :silence`, some work would
301
- still be done on each call to `ActiveSupport::Deprecation.warn`. In very hot paths, this could
302
- cause performance issues.
501
+ verifier.verified(message)
502
+ # => nil
303
503
 
304
- Now, you can make `ActiveSupport::Deprecation.warn` a no-op:
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.
305
517
 
306
518
  ```ruby
307
- 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
308
525
  ```
309
526
 
310
- 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.
311
530
 
312
531
  ```ruby
313
- config.active_support.deprecation = :silence
314
- config.active_support.disallowed_deprecation = :silence
532
+ assert Date.today.in?(..Date.tomorrow)
533
+ assert_not Date.today.in?(Date.tomorrow..)
315
534
  ```
316
535
 
317
- 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.
545
+
546
+ *Alex Ghiculescu*
547
+
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.
318
552
 
319
553
  *Alex Ghiculescu*
320
554
 
321
- * Faster tests by parallelizing only when overhead is justified by the number
322
- of them.
555
+ * `HashWithIndifferentAccess#transform_keys` now takes a Hash argument, just
556
+ as Ruby's `Hash#transform_keys` does.
323
557
 
324
- Running tests in parallel adds overhead in terms of database
325
- setup and fixture loading. Now, Rails will only parallelize test executions when
326
- there are enough tests to make it worth it.
558
+ *Akira Matsuda*
327
559
 
328
- This threshold is 50 by default, and is configurable via config setting in
329
- your test.rb:
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.
330
564
 
331
565
  ```ruby
332
- 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
333
578
  ```
334
579
 
335
- It's also configurable at the test case level:
580
+ *Akira Matsuda*
336
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
337
607
  ```ruby
338
- class ActiveSupport::TestCase
339
- parallelize threshold: 100
608
+ error = assert_raises(ArgumentError) do
609
+ perform_service(param: 'exception')
340
610
  end
611
+ assert_match(/incorrect param/i, error.message)
341
612
  ```
342
613
 
343
- *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
+ ```
344
620
 
345
- * OpenSSL constants are now used for Digest computations.
621
+ *fatkodima*
346
622
 
347
- *Dirkjan Bussink*
623
+ * Add `Rails.env.local?` shorthand for `Rails.env.development? || Rails.env.test?`.
624
+
625
+ *DHH*
348
626
 
349
- * `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method.
350
- A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
351
- and `:yday` fragments returned from `Date._iso8601`.
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)`.
630
+
631
+ *KevSlashNull*, and *serprex*
632
+
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:
352
636
 
353
637
  ```ruby
354
- twz = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].iso8601("21087")
355
- 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
356
642
  ```
357
643
 
358
- *Steve Laing*
644
+ *Alex Ghiculescu*
359
645
 
360
- * `Time#change` and methods that call it (e.g. `Time#advance`) will now
361
- return a `Time` with the timezone argument provided, if the caller was
362
- initialized with a timezone argument.
646
+ * Ensure `ActiveSupport::Testing::Isolation::Forking` closes pipes
363
647
 
364
- Fixes [#42467](https://github.com/rails/rails/issues/42467).
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.
365
653
 
366
- *Alex Ghiculescu*
654
+ This resulted in an accumulation of open file descriptors, which could
655
+ cause errors if the limit is reached.
367
656
 
368
- * Allow serializing any module or class to JSON by name.
657
+ *Sam Bostock*
369
658
 
370
- *Tyler Rick*, *Zachary Scott*
659
+ * Fix `Time#change` and `Time#advance` for times around the end of Daylight
660
+ Saving Time.
371
661
 
372
- * Raise `ActiveSupport::EncryptedFile::MissingKeyError` when the
373
- `RAILS_MASTER_KEY` environment variable is blank (e.g. `""`).
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:
374
665
 
375
- *Sunny Ripert*
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
+ ```
376
684
 
377
- * The `from:` option is added to `ActiveSupport::TestCase#assert_no_changes`.
685
+ And the DST offset would always be chosen for times with a `TimeZone`
686
+ object:
378
687
 
379
- It permits asserting on the initial value that is expected not to change.
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:
380
708
 
381
709
  ```ruby
382
- assert_no_changes -> { Status.all_good? }, from: true do
383
- post :create, params: { status: { ok: true } }
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
+ ```
742
+
743
+ *Kevin Hall*, *Takayoshi Nishida*, and *Jonathan Hefner*
744
+
745
+ * Fix MemoryStore to preserve entries TTL when incrementing or decrementing
746
+
747
+ This is to be more consistent with how MemCachedStore and RedisCacheStore behaves.
748
+
749
+ *Jean Boussier*
750
+
751
+ * `Rails.error.handle` and `Rails.error.record` filter now by multiple error classes.
752
+
753
+ ```ruby
754
+ Rails.error.handle(IOError, ArgumentError) do
755
+ 1 + '1' # raises TypeError
384
756
  end
757
+ 1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
385
758
  ```
386
759
 
387
- *George Claghorn*
760
+ *Martin Spickermann*
761
+
762
+ * `Class#subclasses` and `Class#descendants` now automatically filter reloaded classes.
388
763
 
389
- * Deprecate `ActiveSupport::SafeBuffer`'s incorrect implicit conversion of objects into string.
764
+ Previously they could return old implementations of reloadable classes that have been
765
+ dereferenced but not yet garbage collected.
390
766
 
391
- Except for a few methods like `String#%`, objects must implement `#to_str`
392
- to be implicitly converted to a String in string operations. In some
393
- circumstances `ActiveSupport::SafeBuffer` was incorrectly calling the
394
- explicit conversion method (`#to_s`) on them. This behavior is now
395
- deprecated.
767
+ They now automatically filter such classes like `DescendantTracker#subclasses` and
768
+ `DescendantTracker#descendants`.
396
769
 
397
770
  *Jean Boussier*
398
771
 
399
- * Allow nested access to keys on `Rails.application.credentials`.
772
+ * `Rails.error.report` now marks errors as reported to avoid reporting them twice.
773
+
774
+ In some cases, users might want to report errors explicitly with some extra context
775
+ before letting it bubble up.
400
776
 
401
- Previously only top level keys in `credentials.yml.enc` could be accessed with method calls. Now any key can.
777
+ This also allows to safely catch and report errors outside of the execution context.
778
+
779
+ *Jean Boussier*
402
780
 
403
- For example, given these secrets:
781
+ * Add `assert_error_reported` and `assert_no_error_reported`
404
782
 
405
- ```yml
406
- aws:
407
- access_key_id: 123
408
- secret_access_key: 345
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?
409
793
  ```
410
794
 
411
- `Rails.application.credentials.aws.access_key_id` will now return the same thing as
412
- `Rails.application.credentials.aws[:access_key_id]`.
795
+ *Jean Boussier*
413
796
 
414
- *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.
415
801
 
416
- * 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:
417
804
 
418
- It can be enabled with `config.active_support.cache_format_version = 7.0` or
419
- `config.load_defaults 7.0`. Regardless of the configuration Active Support
420
- 7.0 can read cache entries serialized by Active Support 6.1 which allows to
421
- upgrade without invalidating the cache. However Rails 6.1 can't read the
422
- new format, so all readers must be upgraded before the new format is enabled.
805
+ * `->(message, callstack, deprecator) { ... }`
806
+ * `->(*args) { ... }`
807
+ * `->(message, *other_args) { ... }`
423
808
 
424
- *Jean Boussier*
809
+ 2-arity and 4-arity callbacks such as the following will continue to behave
810
+ the same as before:
425
811
 
426
- * Add `Enumerable#sole`, per `ActiveRecord::FinderMethods#sole`. Returns the
427
- sole item of the enumerable, raising if no items are found, or if more than
428
- one is.
812
+ * `->(message, callstack) { ... }`
813
+ * `->(message, callstack, deprecation_horizon, gem_name) { ... }`
814
+ * `->(message, callstack, *deprecation_details) { ... }`
429
815
 
430
- *Asherah Connor*
816
+ *Jonathan Hefner*
431
817
 
432
- * Freeze `ActiveSupport::Duration#parts` and remove writer methods.
818
+ * `ActiveSupport::Deprecation#disallowed_warnings` now affects the instance on
819
+ which it is configured.
433
820
 
434
- 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`.
435
825
 
436
- *Andrew White*
826
+ **Before**
437
827
 
438
- * 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
+ ```
439
838
 
440
- When `utc_to_local_returns_utc_offset_times` is false and the time
441
- instance had fractional seconds the new UTC time instance was out by
442
- a factor of 1,000,000 as the `Time.utc` constructor takes a usec
443
- value and not a fractional second value.
839
+ **After**
444
840
 
445
- *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*
446
856
 
447
- * 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.
448
862
 
449
863
  ```ruby
450
- Rails.cache.write(key, value, expires_at: Time.now.at_end_of_hour)
864
+ info color("Hello world!", :red, bold: true, underline: true)
451
865
  ```
452
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
+
453
918
  *Jean Boussier*
454
919
 
455
- * 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`.
456
921
 
457
- *Andrew White*
922
+ *Daniel Alfaro*
458
923
 
459
- * Deprecates Rails custom `Enumerable#sum` and `Array#sum` in favor of Ruby's native implementation which
460
- is considerably faster.
924
+ * Add `quarter` method to date/time
461
925
 
462
- Ruby requires an initializer for non-numeric type as per examples below:
926
+ *Matt Swanson*
463
927
 
464
- ```ruby
465
- %w[foo bar].sum('')
466
- # instead of %w[foo bar].sum
928
+ * Fix `NoMethodError` on custom `ActiveSupport::Deprecation` behavior.
467
929
 
468
- [[1, 2], [3, 4, 5]].sum([])
469
- # instead of [[1, 2], [3, 4, 5]].sum
470
- ```
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.
471
933
 
472
- *Alberto Mota*
934
+ This change removes this `arity` restriction of custom behaviors.
473
935
 
474
- * Tests parallelization is now disabled when running individual files to prevent the setup overhead.
936
+ *Ryo Nakamura*
475
937
 
476
- 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`.
477
939
 
478
- *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.
479
943
 
480
- * Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`.
944
+ *Jonathan Hefner*
481
945
 
482
- *Marcin Kołodziej*
946
+ * Add `url_safe` option to `ActiveSupport::MessageVerifier` initializer
483
947
 
484
- * Add `Enumerable#maximum` and `Enumerable#minimum` to easily calculate the maximum or minimum from extracted
485
- 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`.
486
950
 
487
951
  ```ruby
488
- payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
489
-
490
- payments.minimum(:price) # => 5
491
- payments.maximum(:price) # => 15
952
+ verifier = ActiveSupport::MessageVerifier.new(url_safe: true)
953
+ message = verifier.generate(data) # => URL-safe string
492
954
  ```
493
955
 
494
- This also allows passing enumerables to `fresh_when` and `stale?` in Action Controller.
495
- See PR [#41404](https://github.com/rails/rails/pull/41404) for an example.
956
+ This option is `false` by default to be backwards compatible.
496
957
 
497
- *Ayrton De Craene*
958
+ *Shouichi Kamiya*
498
959
 
499
- * `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument.
960
+ * Enable connection pooling by default for `MemCacheStore` and `RedisCacheStore`.
961
+
962
+ If you want to disable connection pooling, set `:pool` option to `false` when configuring the cache store:
500
963
 
501
964
  ```ruby
502
- config.cache_store = :mem_cache_store, nil
965
+ config.cache_store = :mem_cache_store, "cache.example.com", pool: false
966
+ ```
503
967
 
504
- # is now equivalent to
968
+ *fatkodima*
505
969
 
506
- config.cache_store = :mem_cache_store
970
+ * Add `force:` support to `ActiveSupport::Cache::Store#fetch_multi`.
971
+
972
+ *fatkodima*
507
973
 
508
- # and is also equivalent to
974
+ * Deprecated `:pool_size` and `:pool_timeout` options for configuring connection pooling in cache stores.
975
+
976
+ Use `pool: true` to enable pooling with default settings:
977
+
978
+ ```ruby
979
+ config.cache_store = :redis_cache_store, pool: true
980
+ ```
509
981
 
510
- config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
982
+ Or pass individual options via `:pool` option:
511
983
 
512
- # which is the fallback behavior of Dalli
984
+ ```ruby
985
+ config.cache_store = :redis_cache_store, pool: { size: 10, timeout: 2 }
513
986
  ```
514
987
 
515
- This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted.
988
+ *fatkodima*
516
989
 
517
- *Michael Overmeyer*
990
+ * Allow #increment and #decrement methods of `ActiveSupport::Cache::Store`
991
+ subclasses to set new values.
518
992
 
519
- * Add `Enumerable#in_order_of` to put an Enumerable in a certain order by a key.
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.
520
995
 
521
- *DHH*
996
+ *Andrej Blagojević*, *Eugene Kenny*
522
997
 
523
- * `ActiveSupport::Inflector.camelize` behaves expected when provided a symbol `:upper` or `:lower` argument. Matches
524
- `String#camelize` behavior.
998
+ * Add `skip_nil:` support to `RedisCacheStore`
525
999
 
526
- *Alex Ghiculescu*
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*
1013
+
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`.
527
1027
 
528
- * Raises an `ArgumentError` when the first argument of `ActiveSupport::Notification.subscribe` is
529
- invalid.
1028
+ *Steven Harman*
530
1029
 
531
- *Vipul A M*
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*
532
1053
 
533
- * `HashWithIndifferentAccess#deep_transform_keys` now returns a `HashWithIndifferentAccess` instead of a `Hash`.
1054
+ * Deprecate `Notification::Event`'s `#children` and `#parent_of?`
534
1055
 
535
- *Nathaniel Woodthorpe*
1056
+ *John Hawthorn*
536
1057
 
537
- * Consume dalli’s `cache_nils` configuration as `ActiveSupport::Cache`'s `skip_nil` when using `MemCacheStore`.
1058
+ * Change the default serializer of `ActiveSupport::MessageVerifier` from
1059
+ `Marshal` to `ActiveSupport::JSON` when using `config.load_defaults 7.1`.
538
1060
 
539
- *Ritikesh G*
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.
540
1064
 
541
- * Add `RedisCacheStore#stats` method similar to `MemCacheStore#stats`. Calls `redis#info` internally.
1065
+ *Saba Kiaei*, *David Buckley*, and *Jonathan Hefner*
542
1066
 
543
- *Ritikesh G*
1067
+ * Change the default serializer of `ActiveSupport::MessageEncryptor` from
1068
+ `Marshal` to `ActiveSupport::JSON` when using `config.load_defaults 7.1`.
544
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*
1075
+
1076
+ * Add `ActiveSupport::TestCase#stub_const` to stub a constant for the duration of a yield.
1077
+
1078
+ *DHH*
1079
+
1080
+ * Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
1081
+
1082
+ *Stephen Sugden*
1083
+
1084
+ * Improve `File.atomic_write` error handling
1085
+
1086
+ *Daniel Pepper*
1087
+
1088
+ * Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
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*
545
1094
 
546
- 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.