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