activesupport 7.0.4 → 7.1.3.4

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