activesupport 7.0.9 → 7.1.6

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