activesupport 6.1.4.2 → 7.0.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +226 -462
  3. data/MIT-LICENSE +1 -1
  4. data/lib/active_support/actionable_error.rb +1 -1
  5. data/lib/active_support/array_inquirer.rb +0 -2
  6. data/lib/active_support/benchmarkable.rb +2 -2
  7. data/lib/active_support/cache/file_store.rb +15 -9
  8. data/lib/active_support/cache/mem_cache_store.rb +127 -32
  9. data/lib/active_support/cache/memory_store.rb +23 -15
  10. data/lib/active_support/cache/null_store.rb +10 -2
  11. data/lib/active_support/cache/redis_cache_store.rb +42 -67
  12. data/lib/active_support/cache/strategy/local_cache.rb +35 -61
  13. data/lib/active_support/cache.rb +189 -45
  14. data/lib/active_support/callbacks.rb +180 -81
  15. data/lib/active_support/code_generator.rb +65 -0
  16. data/lib/active_support/concern.rb +5 -5
  17. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  18. data/lib/active_support/concurrency/share_lock.rb +2 -2
  19. data/lib/active_support/configurable.rb +6 -3
  20. data/lib/active_support/configuration_file.rb +1 -1
  21. data/lib/active_support/core_ext/array/access.rb +1 -5
  22. data/lib/active_support/core_ext/array/conversions.rb +13 -11
  23. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  24. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  25. data/lib/active_support/core_ext/array.rb +1 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  27. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  28. data/lib/active_support/core_ext/date/blank.rb +1 -1
  29. data/lib/active_support/core_ext/date/calculations.rb +4 -4
  30. data/lib/active_support/core_ext/date/conversions.rb +11 -11
  31. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  32. data/lib/active_support/core_ext/date.rb +1 -0
  33. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  34. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  35. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  36. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  37. data/lib/active_support/core_ext/date_time.rb +1 -0
  38. data/lib/active_support/core_ext/digest/uuid.rb +39 -13
  39. data/lib/active_support/core_ext/enumerable.rb +78 -26
  40. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  41. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  42. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  43. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  44. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  45. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  46. data/lib/active_support/core_ext/name_error.rb +2 -8
  47. data/lib/active_support/core_ext/numeric/conversions.rb +79 -76
  48. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  49. data/lib/active_support/core_ext/numeric.rb +1 -0
  50. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  51. data/lib/active_support/core_ext/object/blank.rb +2 -2
  52. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  53. data/lib/active_support/core_ext/object/duplicable.rb +11 -0
  54. data/lib/active_support/core_ext/object/json.rb +29 -24
  55. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  56. data/lib/active_support/core_ext/object/try.rb +20 -20
  57. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  58. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  59. data/lib/active_support/core_ext/pathname.rb +3 -0
  60. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  61. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  62. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  63. data/lib/active_support/core_ext/range/each.rb +1 -1
  64. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  65. data/lib/active_support/core_ext/range.rb +1 -1
  66. data/lib/active_support/core_ext/string/filters.rb +1 -1
  67. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  68. data/lib/active_support/core_ext/string/output_safety.rb +60 -36
  69. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  70. data/lib/active_support/core_ext/time/calculations.rb +7 -6
  71. data/lib/active_support/core_ext/time/conversions.rb +13 -12
  72. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  73. data/lib/active_support/core_ext/time/zones.rb +4 -19
  74. data/lib/active_support/core_ext/time.rb +1 -0
  75. data/lib/active_support/core_ext/uri.rb +3 -27
  76. data/lib/active_support/core_ext.rb +1 -0
  77. data/lib/active_support/current_attributes.rb +31 -14
  78. data/lib/active_support/dependencies/interlock.rb +10 -18
  79. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  80. data/lib/active_support/dependencies.rb +58 -788
  81. data/lib/active_support/deprecation/behaviors.rb +4 -1
  82. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  83. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  84. data/lib/active_support/deprecation.rb +1 -1
  85. data/lib/active_support/descendants_tracker.rb +174 -68
  86. data/lib/active_support/digest.rb +5 -3
  87. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  88. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  89. data/lib/active_support/duration.rb +81 -51
  90. data/lib/active_support/encrypted_configuration.rb +13 -2
  91. data/lib/active_support/encrypted_file.rb +1 -1
  92. data/lib/active_support/environment_inquirer.rb +1 -1
  93. data/lib/active_support/error_reporter.rb +117 -0
  94. data/lib/active_support/evented_file_update_checker.rb +1 -1
  95. data/lib/active_support/execution_context/test_helper.rb +13 -0
  96. data/lib/active_support/execution_context.rb +53 -0
  97. data/lib/active_support/execution_wrapper.rb +43 -21
  98. data/lib/active_support/executor/test_helper.rb +7 -0
  99. data/lib/active_support/fork_tracker.rb +19 -12
  100. data/lib/active_support/gem_version.rb +4 -4
  101. data/lib/active_support/hash_with_indifferent_access.rb +3 -1
  102. data/lib/active_support/html_safe_translation.rb +43 -0
  103. data/lib/active_support/i18n.rb +1 -0
  104. data/lib/active_support/i18n_railtie.rb +1 -1
  105. data/lib/active_support/inflector/inflections.rb +23 -7
  106. data/lib/active_support/inflector/methods.rb +24 -48
  107. data/lib/active_support/isolated_execution_state.rb +64 -0
  108. data/lib/active_support/json/encoding.rb +3 -3
  109. data/lib/active_support/key_generator.rb +18 -1
  110. data/lib/active_support/locale/en.yml +1 -1
  111. data/lib/active_support/log_subscriber.rb +13 -3
  112. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  113. data/lib/active_support/message_encryptor.rb +8 -3
  114. data/lib/active_support/message_verifier.rb +46 -14
  115. data/lib/active_support/messages/metadata.rb +2 -2
  116. data/lib/active_support/multibyte/chars.rb +10 -11
  117. data/lib/active_support/multibyte/unicode.rb +0 -12
  118. data/lib/active_support/multibyte.rb +1 -1
  119. data/lib/active_support/notifications/fanout.rb +91 -65
  120. data/lib/active_support/notifications/instrumenter.rb +32 -15
  121. data/lib/active_support/notifications.rb +15 -21
  122. data/lib/active_support/number_helper/number_converter.rb +1 -3
  123. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  124. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  125. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  126. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  127. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  128. data/lib/active_support/number_helper.rb +0 -2
  129. data/lib/active_support/option_merger.rb +8 -16
  130. data/lib/active_support/ordered_hash.rb +1 -1
  131. data/lib/active_support/parameter_filter.rb +5 -0
  132. data/lib/active_support/per_thread_registry.rb +5 -0
  133. data/lib/active_support/railtie.rb +69 -19
  134. data/lib/active_support/reloader.rb +1 -1
  135. data/lib/active_support/rescuable.rb +2 -2
  136. data/lib/active_support/ruby_features.rb +7 -0
  137. data/lib/active_support/secure_compare_rotator.rb +1 -1
  138. data/lib/active_support/string_inquirer.rb +0 -2
  139. data/lib/active_support/subscriber.rb +7 -18
  140. data/lib/active_support/tagged_logging.rb +2 -2
  141. data/lib/active_support/test_case.rb +9 -21
  142. data/lib/active_support/testing/assertions.rb +35 -5
  143. data/lib/active_support/testing/deprecation.rb +52 -1
  144. data/lib/active_support/testing/isolation.rb +2 -2
  145. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  146. data/lib/active_support/testing/parallelization/server.rb +4 -0
  147. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  148. data/lib/active_support/testing/parallelization.rb +4 -0
  149. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  150. data/lib/active_support/testing/stream.rb +3 -5
  151. data/lib/active_support/testing/tagged_logging.rb +1 -1
  152. data/lib/active_support/testing/time_helpers.rb +13 -2
  153. data/lib/active_support/time_with_zone.rb +54 -13
  154. data/lib/active_support/values/time_zone.rb +30 -9
  155. data/lib/active_support/xml_mini/jdom.rb +1 -1
  156. data/lib/active_support/xml_mini/libxml.rb +5 -5
  157. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  158. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  159. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  160. data/lib/active_support/xml_mini/rexml.rb +1 -1
  161. data/lib/active_support/xml_mini.rb +5 -4
  162. data/lib/active_support.rb +17 -1
  163. metadata +26 -23
  164. data/lib/active_support/core_ext/marshal.rb +0 -26
  165. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
data/CHANGELOG.md CHANGED
@@ -1,655 +1,419 @@
1
- ## Rails 6.1.4.2 (December 14, 2021) ##
1
+ ## Rails 7.0.2.3 (March 08, 2022) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 6.1.4.1 (August 19, 2021) ##
6
+ ## Rails 7.0.2.2 (February 11, 2022) ##
7
7
 
8
- * No changes.
9
-
10
-
11
- ## Rails 6.1.4 (June 24, 2021) ##
8
+ * Fix Reloader method signature to work with the new Executor signature
12
9
 
13
- * MemCacheStore: convert any underlying value (including `false`) to an `Entry`.
14
10
 
15
- See [#42559](https://github.com/rails/rails/pull/42559).
11
+ ## Rails 7.0.2.1 (February 11, 2022) ##
16
12
 
17
- *Alex Ghiculescu*
13
+ * No changes.
18
14
 
19
- * Fix bug in `number_with_precision` when using large `BigDecimal` values.
20
15
 
21
- Fixes #42302.
16
+ ## Rails 7.0.2 (February 08, 2022) ##
22
17
 
23
- *Federico Aldunate*, *Zachary Scott*
18
+ * Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
24
19
 
25
- * Check byte size instead of length on `secure_compare`.
20
+ *Stephen Sugden*
26
21
 
27
- *Tietew*
22
+ * Improve `File.atomic_write` error handling.
28
23
 
29
- * Fix `Time.at` to not lose `:in` option.
24
+ *Daniel Pepper*
30
25
 
31
- *Ryuta Kamizono*
32
26
 
33
- * Require a path for `config.cache_store = :file_store`.
27
+ ## Rails 7.0.1 (January 06, 2022) ##
34
28
 
35
- *Alex Ghiculescu*
29
+ * Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
36
30
 
37
- * Avoid having to store complex object in the default translation file.
31
+ [The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33),
32
+ but `Class#subclasses` was kept, breaking the feature detection.
38
33
 
39
- *Rafael Mendonça França*
34
+ *Jean Boussier*
40
35
 
41
36
 
42
- ## Rails 6.1.3.2 (May 05, 2021) ##
37
+ ## Rails 7.0.0 (December 15, 2021) ##
43
38
 
44
- * No changes.
39
+ * Fix `ActiveSupport::Duration.build` to support negative values.
45
40
 
41
+ The algorithm to collect the `parts` of the `ActiveSupport::Duration`
42
+ ignored the sign of the `value` and accumulated incorrect part values. This
43
+ impacted `ActiveSupport::Duration#sum` (which is dependent on `parts`) but
44
+ not `ActiveSupport::Duration#eql?` (which is dependent on `value`).
46
45
 
47
- ## Rails 6.1.3.1 (March 26, 2021) ##
48
-
49
- * No changes.
46
+ *Caleb Buxton*, *Braden Staudacher*
50
47
 
51
48
 
52
- ## Rails 6.1.3 (February 17, 2021) ##
49
+ ## Rails 7.0.0.rc3 (December 14, 2021) ##
53
50
 
54
51
  * No changes.
55
52
 
56
53
 
57
- ## Rails 6.1.2.1 (February 10, 2021) ##
54
+ ## Rails 7.0.0.rc2 (December 14, 2021) ##
58
55
 
59
56
  * No changes.
60
57
 
58
+ ## Rails 7.0.0.rc1 (December 06, 2021) ##
61
59
 
62
- ## Rails 6.1.2 (February 09, 2021) ##
60
+ * Deprecate passing a format to `#to_s` in favor of `#to_formatted_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
61
+ `BigDecimal`, `Float` and, `Integer`.
63
62
 
64
- * `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument.
65
-
66
- ```ruby
67
- config.cache_store = :mem_cache_store, nil
68
-
69
- # is now equivalent to
70
-
71
- config.cache_store = :mem_cache_store
72
-
73
- # and is also equivalent to
74
-
75
- config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
76
-
77
- # which is the fallback behavior of Dalli
78
- ```
79
-
80
- This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted.
81
-
82
- *Michael Overmeyer*
83
-
84
-
85
- ## Rails 6.1.1 (January 07, 2021) ##
86
-
87
- * Change `IPAddr#to_json` to match the behavior of the json gem returning the string representation
88
- instead of the instance variables of the object.
63
+ *Rafael Mendonça França*
89
64
 
90
- Before:
65
+ * Document `ActiveSupport::Testing::Deprecation`.
91
66
 
92
- ```ruby
93
- IPAddr.new("127.0.0.1").to_json
94
- # => "{\"addr\":2130706433,\"family\":2,\"mask_addr\":4294967295}"
95
- ```
67
+ *Sam Bostock & Sam Jordan*
96
68
 
97
- After:
69
+ * Add `Pathname#existence`.
98
70
 
99
71
  ```ruby
100
- IPAddr.new("127.0.0.1").to_json
101
- # => "\"127.0.0.1\""
72
+ Pathname.new("file").existence&.read
102
73
  ```
103
74
 
75
+ *Timo Schilling*
104
76
 
105
- ## Rails 6.1.0 (December 09, 2020) ##
106
-
107
- * Ensure `MemoryStore` disables compression by default. Reverts behavior of
108
- `MemoryStore` to its prior rails `5.1` behavior.
109
-
110
- *Max Gurewitz*
111
-
112
- * Calling `iso8601` on negative durations retains the negative sign on individual
113
- digits instead of prepending it.
114
-
115
- This change is required so we can interoperate with PostgreSQL, which prefers
116
- negative signs for each component.
117
-
118
- Compatibility with other iso8601 parsers which support leading negatives as well
119
- as negatives per component is still retained.
120
-
121
- Before:
122
-
123
- (-1.year - 1.day).iso8601
124
- # => "-P1Y1D"
125
-
126
- After:
127
-
128
- (-1.year - 1.day).iso8601
129
- # => "P-1Y-1D"
130
-
131
- *Vipul A M*
132
-
133
- * Remove deprecated `ActiveSupport::Notifications::Instrumenter#end=`.
77
+ * Remove deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
134
78
 
135
79
  *Rafael Mendonça França*
136
80
 
137
- * Deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
81
+ * Remove deprecated support to use `Range#include?` to check the inclusion of a value in
82
+ a date time range is deprecated.
138
83
 
139
84
  *Rafael Mendonça França*
140
85
 
141
- * Remove deprecated `ActiveSupport::Multibyte::Unicode.pack_graphemes`,
142
- `ActiveSupport::Multibyte::Unicode.unpack_graphemes`,
143
- `ActiveSupport::Multibyte::Unicode.normalize`,
144
- `ActiveSupport::Multibyte::Unicode.downcase`,
145
- `ActiveSupport::Multibyte::Unicode.upcase` and `ActiveSupport::Multibyte::Unicode.swapcase`.
86
+ * Remove deprecated `URI.parser`.
146
87
 
147
88
  *Rafael Mendonça França*
148
89
 
149
- * Remove deprecated `ActiveSupport::Multibyte::Chars#consumes?` and `ActiveSupport::Multibyte::Chars#normalize`.
90
+ * Remove deprecated `config.active_support.use_sha1_digests`.
150
91
 
151
92
  *Rafael Mendonça França*
152
93
 
153
- * Remove deprecated file `active_support/core_ext/range/include_range`.
154
-
155
- *Rafael Mendonça França*
156
-
157
- * Remove deprecated file `active_support/core_ext/hash/transform_values`.
158
-
159
- *Rafael Mendonça França*
160
-
161
- * Remove deprecated file `active_support/core_ext/hash/compact`.
162
-
163
- *Rafael Mendonça França*
164
-
165
- * Remove deprecated file `active_support/core_ext/array/prepend_and_append`.
166
-
167
- *Rafael Mendonça França*
168
-
169
- * Remove deprecated file `active_support/core_ext/numeric/inquiry`.
170
-
171
- *Rafael Mendonça França*
172
-
173
- * Remove deprecated file `active_support/core_ext/module/reachable`.
174
-
175
- *Rafael Mendonça França*
176
-
177
- * Remove deprecated `Module#parent_name`, `Module#parent` and `Module#parents`.
178
-
179
- *Rafael Mendonça França*
180
-
181
- * Remove deprecated `ActiveSupport::LoggerThreadSafeLevel#after_initialize`.
182
-
183
- *Rafael Mendonça França*
184
-
185
- * Remove deprecated `LoggerSilence` constant.
186
-
187
- *Rafael Mendonça França*
188
-
189
- * Remove deprecated fallback to `I18n.default_local` when `config.i18n.fallbacks` is empty.
190
-
191
- *Rafael Mendonça França*
192
-
193
- * Remove entries from local cache on `RedisCacheStore#delete_matched`
194
-
195
- Fixes #38627
196
-
197
- *ojab*
198
-
199
- * Speed up `ActiveSupport::SecurityUtils.fixed_length_secure_compare` by using
200
- `OpenSSL.fixed_length_secure_compare`, if available.
201
-
202
- *Nate Matykiewicz*
94
+ * Invoking `Object#with_options` without a `&block` argument returns the
95
+ `ActiveSupport::OptionMerger` instance.
203
96
 
204
- * `ActiveSupport::Cache::MemCacheStore` now checks `ENV["MEMCACHE_SERVERS"]` before falling back to `"localhost:11211"` if configured without any addresses.
97
+ *Sean Doyle*
205
98
 
206
- ```ruby
207
- config.cache_store = :mem_cache_store
99
+ * `Rails.application.executor` hooks can now be called around every test
208
100
 
209
- # is now equivalent to
101
+ This helps to better simulate request or job local state being reset around tests and prevents state
102
+ leaking from one test to another.
210
103
 
211
- config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
104
+ However it requires the executor hooks executed in the test environment to be re-entrant.
212
105
 
213
- # instead of
106
+ To enable this, set `config.active_support.executor_around_test_case = true` (this is the default in Rails 7).
214
107
 
215
- config.cache_store = :mem_cache_store, "localhost:11211" # ignores ENV["MEMCACHE_SERVERS"]
216
- ```
108
+ *Jean Boussier*
217
109
 
218
- *Sam Bostock*
110
+ * `ActiveSupport::DescendantsTracker` now mostly delegate to `Class#descendants` on Ruby 3.1
219
111
 
220
- * `ActiveSupport::Subscriber#attach_to` now accepts an `inherit_all:` argument. When set to true,
221
- it allows a subscriber to receive events for methods defined in the subscriber's ancestor class(es).
112
+ Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless.
222
113
 
223
- ```ruby
224
- class ActionControllerSubscriber < ActiveSupport::Subscriber
225
- attach_to :action_controller
114
+ As a result the following methods are deprecated:
226
115
 
227
- def start_processing(event)
228
- info "Processing by #{event.payload[:controller]}##{event.payload[:action]} as #{format}"
229
- end
116
+ - `ActiveSupport::DescendantsTracker.direct_descendants`
117
+ - `ActiveSupport::DescendantsTracker#direct_descendants`
230
118
 
231
- def redirect_to(event)
232
- info { "Redirected to #{event.payload[:location]}" }
233
- end
234
- end
119
+ *Jean Boussier*
235
120
 
236
- # We detach ActionControllerSubscriber from the :action_controller namespace so that our CustomActionControllerSubscriber
237
- # can provide its own instrumentation for certain events in the namespace
238
- ActionControllerSubscriber.detach_from(:action_controller)
121
+ * Fix the `Digest::UUID.uuid_from_hash` behavior for namespace IDs that are different from the ones defined on `Digest::UUID`.
239
122
 
240
- class CustomActionControllerSubscriber < ActionControllerSubscriber
241
- attach_to :action_controller, inherit_all: true
123
+ The new behavior will be enabled by setting the
124
+ `config.active_support.use_rfc4122_namespaced_uuids` option to `true`
125
+ and is the default for new apps.
242
126
 
243
- def start_processing(event)
244
- info "A custom response to start_processing events"
245
- end
127
+ The old behavior is the default for upgraded apps and will output a
128
+ deprecation warning every time a value that is different than one of
129
+ the constants defined on the `Digest::UUID` extension is used as the
130
+ namespace ID.
246
131
 
247
- # => CustomActionControllerSubscriber will process events for "start_processing.action_controller" notifications
248
- # using its own #start_processing implementation, while retaining ActionControllerSubscriber's instrumentation
249
- # for "redirect_to.action_controller" notifications
250
- end
251
- ```
132
+ *Alex Robbin*, *Erich Soares Machado*, *Eugene Kenny*
252
133
 
253
- *Adrianna Chang*
134
+ * `ActiveSupport::Inflector::Inflections#clear(:acronyms)` is now supported,
135
+ and `inflector.clear` / `inflector.clear(:all)` also clears acronyms.
254
136
 
255
- * Allow the digest class used to generate non-sensitive digests to be configured with `config.active_support.hash_digest_class`.
137
+ *Alex Ghiculescu*, *Oliver Peate*
256
138
 
257
- `config.active_support.use_sha1_digests` is deprecated in favour of `config.active_support.hash_digest_class = ::Digest::SHA1`.
258
139
 
259
- *Dirkjan Bussink*
140
+ ## Rails 7.0.0.alpha2 (September 15, 2021) ##
260
141
 
261
- * Fix bug to make memcached write_entry expire correctly with unless_exist
142
+ * No changes.
262
143
 
263
- *Jye Lee*
264
144
 
265
- * Add `ActiveSupport::Duration` conversion methods
145
+ ## Rails 7.0.0.alpha1 (September 15, 2021) ##
266
146
 
267
- `in_seconds`, `in_minutes`, `in_hours`, `in_days`, `in_weeks`, `in_months`, and `in_years` return the respective duration covered.
147
+ * `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.
268
148
 
269
- *Jason York*
149
+ *Xavier Noria*
270
150
 
271
- * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
272
- to `read_multi` causing `fetch_multi` to not work properly
151
+ * Private internal classes of `ActiveSupport::Dependencies` have been deleted, like `ActiveSupport::Dependencies::Reference`, `ActiveSupport::Dependencies::Blamable`, and others.
273
152
 
274
- *Rajesh Sharma*
153
+ *Xavier Noria*
275
154
 
276
- * Fixed issue in `ActiveSupport::Cache::MemCacheStore` which caused duplicate compression,
277
- and caused the provided `compression_threshold` to not be respected.
155
+ * The private API of `ActiveSupport::Dependencies` has been deleted. That includes methods like `hook!`, `unhook!`, `depend_on`, `require_or_load`, `mechanism`, and many others.
278
156
 
279
- *Max Gurewitz*
157
+ *Xavier Noria*
280
158
 
281
- * Prevent `RedisCacheStore` and `MemCacheStore` from performing compression
282
- when reading entries written with `raw: true`.
159
+ * Improves the performance of `ActiveSupport::NumberHelper` formatters by avoiding the use of exceptions as flow control.
283
160
 
284
- *Max Gurewitz*
161
+ *Mike Dalessio*
285
162
 
286
- * `URI.parser` is deprecated and will be removed in Rails 6.2. Use
287
- `URI::DEFAULT_PARSER` instead.
163
+ * Removed rescue block from `ActiveSupport::Cache::RedisCacheStore#handle_exception`
288
164
 
289
- *Jean Boussier*
165
+ Previously, if you provided a `error_handler` to `redis_cache_store`, any errors thrown by
166
+ the error handler would be rescued and logged only. Removed the `rescue` clause from `handle_exception`
167
+ to allow these to be thrown.
290
168
 
291
- * `require_dependency` has been documented to be _obsolete_ in `:zeitwerk`
292
- mode. The method is not deprecated as such (yet), but applications are
293
- encouraged to not use it.
169
+ *Nicholas A. Stuart*
294
170
 
295
- In `:zeitwerk` mode, semantics match Ruby's and you do not need to be
296
- defensive with load order. Just refer to classes and modules normally. If
297
- the constant name is dynamic, camelize if needed, and constantize.
171
+ * Allow entirely opting out of deprecation warnings.
298
172
 
299
- *Xavier Noria*
173
+ Previously if you did `app.config.active_support.deprecation = :silence`, some work would
174
+ still be done on each call to `ActiveSupport::Deprecation.warn`. In very hot paths, this could
175
+ cause performance issues.
300
176
 
301
- * Add 3rd person aliases of `Symbol#start_with?` and `Symbol#end_with?`.
177
+ Now, you can make `ActiveSupport::Deprecation.warn` a no-op:
302
178
 
303
179
  ```ruby
304
- :foo.starts_with?("f") # => true
305
- :foo.ends_with?("o") # => true
180
+ config.active_support.report_deprecations = false
306
181
  ```
307
182
 
308
- *Ryuta Kamizono*
309
-
310
- * Add override of unary plus for `ActiveSupport::Duration`.
183
+ This is the default in production for new apps. It is the equivalent to:
311
184
 
312
- `+ 1.second` is now identical to `+1.second` to prevent errors
313
- where a seemingly innocent change of formatting leads to a change in the code behavior.
314
-
315
- Before:
316
185
  ```ruby
317
- +1.second.class
318
- # => ActiveSupport::Duration
319
- (+ 1.second).class
320
- # => Integer
186
+ config.active_support.deprecation = :silence
187
+ config.active_support.disallowed_deprecation = :silence
321
188
  ```
322
189
 
323
- After:
324
- ```ruby
325
- +1.second.class
326
- # => ActiveSupport::Duration
327
- (+ 1.second).class
328
- # => ActiveSupport::Duration
329
- ```
330
-
331
- Fixes #39079.
332
-
333
- *Roman Kushnir*
334
-
335
- * Add subsec to `ActiveSupport::TimeWithZone#inspect`.
336
-
337
- Before:
190
+ but will take a more optimised code path.
338
191
 
339
- Time.at(1498099140).in_time_zone.inspect
340
- # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
341
- Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
342
- # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
343
- Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
344
- # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
345
-
346
- After:
192
+ *Alex Ghiculescu*
347
193
 
348
- Time.at(1498099140).in_time_zone.inspect
349
- # => "Thu, 22 Jun 2017 02:39:00.000000000 UTC +00:00"
350
- Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
351
- # => "Thu, 22 Jun 2017 02:39:00.123456780 UTC +00:00"
352
- Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
353
- # => "Thu, 22 Jun 2017 02:39:00.333333333 UTC +00:00"
194
+ * Faster tests by parallelizing only when overhead is justified by the number
195
+ of them.
354
196
 
355
- *akinomaeni*
197
+ Running tests in parallel adds overhead in terms of database
198
+ setup and fixture loading. Now, Rails will only parallelize test executions when
199
+ there are enough tests to make it worth it.
356
200
 
357
- * Calling `ActiveSupport::TaggedLogging#tagged` without a block now returns a tagged logger.
201
+ This threshold is 50 by default, and is configurable via config setting in
202
+ your test.rb:
358
203
 
359
204
  ```ruby
360
- logger.tagged("BCX").info("Funky time!") # => [BCX] Funky time!
205
+ config.active_support.test_parallelization_threshold = 100
361
206
  ```
362
207
 
363
- *Eugene Kenny*
364
-
365
- * Align `Range#cover?` extension behavior with Ruby behavior for backwards ranges.
366
-
367
- `(1..10).cover?(5..3)` now returns `false`, as it does in plain Ruby.
368
-
369
- Also update `#include?` and `#===` behavior to match.
208
+ It's also configurable at the test case level:
370
209
 
371
- *Michael Groeneman*
372
-
373
- * Update to TZInfo v2.0.0.
374
-
375
- This changes the output of `ActiveSupport::TimeZone.utc_to_local`, but
376
- can be controlled with the
377
- `ActiveSupport.utc_to_local_returns_utc_offset_times` config.
378
-
379
- New Rails 6.1 apps have it enabled by default, existing apps can upgrade
380
- via the config in config/initializers/new_framework_defaults_6_1.rb
381
-
382
- See the `utc_to_local_returns_utc_offset_times` documentation for details.
383
-
384
- *Phil Ross*, *Jared Beck*
385
-
386
- * Add Date and Time `#yesterday?` and `#tomorrow?` alongside `#today?`.
387
-
388
- Aliased to `#prev_day?` and `#next_day?` to match the existing `#prev/next_day` methods.
389
-
390
- *Jatin Dhankhar*
210
+ ```ruby
211
+ class ActiveSupport::TestCase
212
+ parallelize threshold: 100
213
+ end
214
+ ```
391
215
 
392
- * Add `Enumerable#pick` to complement `ActiveRecord::Relation#pick`.
216
+ *Jorge Manrubia*
393
217
 
394
- *Eugene Kenny*
218
+ * OpenSSL constants are now used for Digest computations.
395
219
 
396
- * [Breaking change] `ActiveSupport::Callbacks#halted_callback_hook` now receive a 2nd argument:
220
+ *Dirkjan Bussink*
397
221
 
398
- `ActiveSupport::Callbacks#halted_callback_hook` now receive the name of the callback
399
- being halted as second argument.
400
- This change will allow you to differentiate which callbacks halted the chain
401
- and act accordingly.
222
+ * `TimeZone.iso8601` now accepts valid ordinal values similar to Ruby's `Date._iso8601` method.
223
+ A valid ordinal value will be converted to an instance of `TimeWithZone` using the `:year`
224
+ and `:yday` fragments returned from `Date._iso8601`.
402
225
 
403
226
  ```ruby
404
- class Book < ApplicationRecord
405
- before_save { throw(:abort) }
406
- before_create { throw(:abort) }
407
-
408
- def halted_callback_hook(filter, callback_name)
409
- Rails.logger.info("Book couldn't be #{callback_name}d")
410
- end
411
-
412
- Book.create # => "Book couldn't be created"
413
- book.save # => "Book couldn't be saved"
414
- end
227
+ twz = ActiveSupport::TimeZone["Eastern Time (US & Canada)"].iso8601("21087")
228
+ twz.to_a[0, 6] == [0, 0, 0, 28, 03, 2021]
415
229
  ```
416
230
 
417
- *Edouard Chin*
418
-
419
- * Support `prepend` with `ActiveSupport::Concern`.
231
+ *Steve Laing*
420
232
 
421
- Allows a module with `extend ActiveSupport::Concern` to be prepended.
233
+ * `Time#change` and methods that call it (e.g. `Time#advance`) will now
234
+ return a `Time` with the timezone argument provided, if the caller was
235
+ initialized with a timezone argument.
422
236
 
423
- module Imposter
424
- extend ActiveSupport::Concern
237
+ Fixes [#42467](https://github.com/rails/rails/issues/42467).
425
238
 
426
- # Same as `included`, except only run when prepended.
427
- prepended do
428
- end
429
- end
239
+ *Alex Ghiculescu*
430
240
 
431
- class Person
432
- prepend Imposter
433
- end
241
+ * Allow serializing any module or class to JSON by name.
434
242
 
435
- Class methods are prepended to the base class, concerning is also
436
- updated: `concerning :Imposter, prepend: true do`.
243
+ *Tyler Rick*, *Zachary Scott*
437
244
 
438
- *Jason Karns*, *Elia Schito*
245
+ * Raise `ActiveSupport::EncryptedFile::MissingKeyError` when the
246
+ `RAILS_MASTER_KEY` environment variable is blank (e.g. `""`).
439
247
 
440
- * Deprecate using `Range#include?` method to check the inclusion of a value
441
- in a date time range. It is recommended to use `Range#cover?` method
442
- instead of `Range#include?` to check the inclusion of a value
443
- in a date time range.
248
+ *Sunny Ripert*
444
249
 
445
- *Vishal Telangre*
250
+ * The `from:` option is added to `ActiveSupport::TestCase#assert_no_changes`.
446
251
 
447
- * Support added for a `round_mode` parameter, in all number helpers. (See: `BigDecimal::mode`.)
252
+ It permits asserting on the initial value that is expected not to change.
448
253
 
449
254
  ```ruby
450
- number_to_currency(1234567890.50, precision: 0, round_mode: :half_down) # => "$1,234,567,890"
451
- number_to_percentage(302.24398923423, precision: 5, round_mode: :down) # => "302.24398%"
452
- number_to_rounded(389.32314, precision: 0, round_mode: :ceil) # => "390"
453
- number_to_human_size(483989, precision: 2, round_mode: :up) # => "480 KB"
454
- number_to_human(489939, precision: 2, round_mode: :floor) # => "480 Thousand"
455
-
456
- 485000.to_s(:human, precision: 2, round_mode: :half_even) # => "480 Thousand"
255
+ assert_no_changes -> { Status.all_good? }, from: true do
256
+ post :create, params: { status: { ok: true } }
257
+ end
457
258
  ```
458
259
 
459
- *Tom Lord*
460
-
461
- * `Array#to_sentence` no longer returns a frozen string.
462
-
463
- Before:
464
-
465
- ['one', 'two'].to_sentence.frozen?
466
- # => true
260
+ *George Claghorn*
467
261
 
468
- After:
262
+ * Deprecate `ActiveSupport::SafeBuffer`'s incorrect implicit conversion of objects into string.
469
263
 
470
- ['one', 'two'].to_sentence.frozen?
471
- # => false
264
+ Except for a few methods like `String#%`, objects must implement `#to_str`
265
+ to be implicitly converted to a String in string operations. In some
266
+ circumstances `ActiveSupport::SafeBuffer` was incorrectly calling the
267
+ explicit conversion method (`#to_s`) on them. This behavior is now
268
+ deprecated.
472
269
 
473
- *Nicolas Dular*
474
-
475
- * When an instance of `ActiveSupport::Duration` is converted to an `iso8601` duration string, if `weeks` are mixed with `date` parts, the `week` part will be converted to days.
476
- This keeps the parser and serializer on the same page.
477
-
478
- ```ruby
479
- duration = ActiveSupport::Duration.build(1000000)
480
- # 1 week, 4 days, 13 hours, 46 minutes, and 40.0 seconds
481
-
482
- duration_iso = duration.iso8601
483
- # P11DT13H46M40S
270
+ *Jean Boussier*
484
271
 
485
- ActiveSupport::Duration.parse(duration_iso)
486
- # 11 days, 13 hours, 46 minutes, and 40 seconds
272
+ * Allow nested access to keys on `Rails.application.credentials`.
487
273
 
488
- duration = ActiveSupport::Duration.build(604800)
489
- # 1 week
274
+ Previously only top level keys in `credentials.yml.enc` could be accessed with method calls. Now any key can.
490
275
 
491
- duration_iso = duration.iso8601
492
- # P1W
276
+ For example, given these secrets:
493
277
 
494
- ActiveSupport::Duration.parse(duration_iso)
495
- # 1 week
278
+ ```yml
279
+ aws:
280
+ access_key_id: 123
281
+ secret_access_key: 345
496
282
  ```
497
283
 
498
- *Abhishek Sarkar*
284
+ `Rails.application.credentials.aws.access_key_id` will now return the same thing as
285
+ `Rails.application.credentials.aws[:access_key_id]`.
499
286
 
500
- * Add block support to `ActiveSupport::Testing::TimeHelpers#travel_back`.
501
-
502
- *Tim Masliuchenko*
503
-
504
- * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
505
- `ActiveSupport.parse_json_times = true`.
506
-
507
- *Christian Gregg*
287
+ *Alex Ghiculescu*
508
288
 
509
- * Support symbolic links for `content_path` in `ActiveSupport::EncryptedFile`.
289
+ * Added a faster and more compact `ActiveSupport::Cache` serialization format.
510
290
 
511
- *Takumi Shotoku*
291
+ It can be enabled with `config.active_support.cache_format_version = 7.0` or
292
+ `config.load_defaults 7.0`. Regardless of the configuration Active Support
293
+ 7.0 can read cache entries serialized by Active Support 6.1 which allows to
294
+ upgrade without invalidating the cache. However Rails 6.1 can't read the
295
+ new format, so all readers must be upgraded before the new format is enabled.
512
296
 
513
- * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
514
- and endless range targets.
297
+ *Jean Boussier*
515
298
 
516
- *Allen Hsu*, *Andrew Hodgkinson*
299
+ * Add `Enumerable#sole`, per `ActiveRecord::FinderMethods#sole`. Returns the
300
+ sole item of the enumerable, raising if no items are found, or if more than
301
+ one is.
517
302
 
518
- * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
303
+ *Asherah Connor*
519
304
 
520
- *Iain Beeston*
305
+ * Freeze `ActiveSupport::Duration#parts` and remove writer methods.
521
306
 
522
- * Prevent `ActiveSupport::Duration.build(value)` from creating instances of
523
- `ActiveSupport::Duration` unless `value` is of type `Numeric`.
307
+ Durations are meant to be value objects and should not be mutated.
524
308
 
525
- Addresses the errant set of behaviours described in #37012 where
526
- `ActiveSupport::Duration` comparisons would fail confusingly
527
- or return unexpected results when comparing durations built from instances of `String`.
309
+ *Andrew White*
528
310
 
529
- Before:
311
+ * Fix `ActiveSupport::TimeZone#utc_to_local` with fractional seconds.
530
312
 
531
- small_duration_from_string = ActiveSupport::Duration.build('9')
532
- large_duration_from_string = ActiveSupport::Duration.build('100000000000000')
533
- small_duration_from_int = ActiveSupport::Duration.build(9)
313
+ When `utc_to_local_returns_utc_offset_times` is false and the time
314
+ instance had fractional seconds the new UTC time instance was out by
315
+ a factor of 1,000,000 as the `Time.utc` constructor takes a usec
316
+ value and not a fractional second value.
534
317
 
535
- large_duration_from_string > small_duration_from_string
536
- # => false
318
+ *Andrew White*
537
319
 
538
- small_duration_from_string == small_duration_from_int
539
- # => false
320
+ * Add `expires_at` argument to `ActiveSupport::Cache` `write` and `fetch` to set a cache entry TTL as an absolute time.
540
321
 
541
- small_duration_from_int < large_duration_from_string
542
- # => ArgumentError (comparison of ActiveSupport::Duration::Scalar with ActiveSupport::Duration failed)
322
+ ```ruby
323
+ Rails.cache.write(key, value, expires_at: Time.now.at_end_of_hour)
324
+ ```
543
325
 
544
- large_duration_from_string > small_duration_from_int
545
- # => ArgumentError (comparison of String with ActiveSupport::Duration failed)
326
+ *Jean Boussier*
546
327
 
547
- After:
328
+ * Deprecate `ActiveSupport::TimeWithZone.name` so that from Rails 7.1 it will use the default implementation.
548
329
 
549
- small_duration_from_string = ActiveSupport::Duration.build('9')
550
- # => TypeError (can't build an ActiveSupport::Duration from a String)
330
+ *Andrew White*
551
331
 
552
- *Alexei Emam*
332
+ * Deprecates Rails custom `Enumerable#sum` and `Array#sum` in favor of Ruby's native implementation which
333
+ is considerably faster.
553
334
 
554
- * Add `ActiveSupport::Cache::Store#delete_multi` method to delete multiple keys from the cache store.
335
+ Ruby requires an initializer for non-numeric type as per examples below:
555
336
 
556
- *Peter Zhu*
337
+ ```ruby
338
+ %w[foo bar].sum('')
339
+ # instead of %w[foo bar].sum
557
340
 
558
- * Support multiple arguments in `HashWithIndifferentAccess` for `merge` and `update` methods, to
559
- follow Ruby 2.6 addition.
341
+ [[1, 2], [3, 4, 5]].sum([])
342
+ # instead of [[1, 2], [3, 4, 5]].sum
343
+ ```
560
344
 
561
- *Wojciech Wnętrzak*
345
+ *Alberto Mota*
562
346
 
563
- * Allow initializing `thread_mattr_*` attributes via `:default` option.
347
+ * Tests parallelization is now disabled when running individual files to prevent the setup overhead.
564
348
 
565
- class Scraper
566
- thread_mattr_reader :client, default: Api::Client.new
567
- end
349
+ It can still be enforced if the environment variable `PARALLEL_WORKERS` is present and set to a value greater than 1.
568
350
 
569
- *Guilherme Mansur*
351
+ *Ricardo Díaz*
570
352
 
571
- * Add `compact_blank` for those times when you want to remove #blank? values from
572
- an Enumerable (also `compact_blank!` on Hash, Array, ActionController::Parameters).
353
+ * Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`.
573
354
 
574
- *Dana Sherson*
355
+ *Marcin Kołodziej*
575
356
 
576
- * Make ActiveSupport::Logger Fiber-safe.
357
+ * Add `Enumerable#maximum` and `Enumerable#minimum` to easily calculate the maximum or minimum from extracted
358
+ elements of an enumerable.
577
359
 
578
- Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
579
- to make log level local to Ruby Fibers in addition to Threads.
360
+ ```ruby
361
+ payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
580
362
 
581
- Example:
363
+ payments.minimum(:price) # => 5
364
+ payments.maximum(:price) # => 15
365
+ ```
582
366
 
583
- logger = ActiveSupport::Logger.new(STDOUT)
584
- logger.level = 1
585
- puts "Main is debug? #{logger.debug?}"
367
+ This also allows passing enumerables to `fresh_when` and `stale?` in Action Controller.
368
+ See PR [#41404](https://github.com/rails/rails/pull/41404) for an example.
586
369
 
587
- Fiber.new {
588
- logger.local_level = 0
589
- puts "Thread is debug? #{logger.debug?}"
590
- }.resume
370
+ *Ayrton De Craene*
591
371
 
592
- puts "Main is debug? #{logger.debug?}"
372
+ * `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument.
593
373
 
594
- Before:
374
+ ```ruby
375
+ config.cache_store = :mem_cache_store, nil
595
376
 
596
- Main is debug? false
597
- Thread is debug? true
598
- Main is debug? true
377
+ # is now equivalent to
599
378
 
600
- After:
379
+ config.cache_store = :mem_cache_store
601
380
 
602
- Main is debug? false
603
- Thread is debug? true
604
- Main is debug? false
381
+ # and is also equivalent to
605
382
 
606
- Fixes #36752.
383
+ config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
607
384
 
608
- *Alexander Varnin*
385
+ # which is the fallback behavior of Dalli
386
+ ```
609
387
 
610
- * Allow the `on_rotation` proc used when decrypting/verifying a message to be
611
- passed at the constructor level.
388
+ This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted.
612
389
 
613
- Before:
390
+ *Michael Overmeyer*
614
391
 
615
- crypt = ActiveSupport::MessageEncryptor.new('long_secret')
616
- crypt.decrypt_and_verify(encrypted_message, on_rotation: proc { ... })
617
- crypt.decrypt_and_verify(another_encrypted_message, on_rotation: proc { ... })
392
+ * Add `Enumerable#in_order_of` to put an Enumerable in a certain order by a key.
618
393
 
619
- After:
394
+ *DHH*
620
395
 
621
- crypt = ActiveSupport::MessageEncryptor.new('long_secret', on_rotation: proc { ... })
622
- crypt.decrypt_and_verify(encrypted_message)
623
- crypt.decrypt_and_verify(another_encrypted_message)
396
+ * `ActiveSupport::Inflector.camelize` behaves expected when provided a symbol `:upper` or `:lower` argument. Matches
397
+ `String#camelize` behavior.
624
398
 
625
- *Edouard Chin*
399
+ *Alex Ghiculescu*
626
400
 
627
- * `delegate_missing_to` would raise a `DelegationError` if the object
628
- delegated to was `nil`. Now the `allow_nil` option has been added to enable
629
- the user to specify they want `nil` returned in this case.
401
+ * Raises an `ArgumentError` when the first argument of `ActiveSupport::Notification.subscribe` is
402
+ invalid.
630
403
 
631
- *Matthew Tanous*
404
+ *Vipul A M*
632
405
 
633
- * `truncate` would return the original string if it was too short to be truncated
634
- and a frozen string if it were long enough to be truncated. Now truncate will
635
- consistently return an unfrozen string regardless. This behavior is consistent
636
- with `gsub` and `strip`.
406
+ * `HashWithIndifferentAccess#deep_transform_keys` now returns a `HashWithIndifferentAccess` instead of a `Hash`.
637
407
 
638
- Before:
408
+ *Nathaniel Woodthorpe*
639
409
 
640
- 'foobar'.truncate(5).frozen?
641
- # => true
642
- 'foobar'.truncate(6).frozen?
643
- # => false
410
+ * Consume dalli’s `cache_nils` configuration as `ActiveSupport::Cache`'s `skip_nil` when using `MemCacheStore`.
644
411
 
645
- After:
412
+ *Ritikesh G*
646
413
 
647
- 'foobar'.truncate(5).frozen?
648
- # => false
649
- 'foobar'.truncate(6).frozen?
650
- # => false
414
+ * Add `RedisCacheStore#stats` method similar to `MemCacheStore#stats`. Calls `redis#info` internally.
651
415
 
652
- *Jordan Thomas*
416
+ *Ritikesh G*
653
417
 
654
418
 
655
- Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activesupport/CHANGELOG.md) for previous changes.
419
+ Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activesupport/CHANGELOG.md) for previous changes.