activesupport 7.0.8.1 → 7.1.3.2

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