activesupport 6.1.4.1 → 7.0.1

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