activesupport 5.1.1 → 6.1.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 (262) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -442
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +65 -53
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +68 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +305 -127
  19. data/lib/active_support/callbacks.rb +106 -98
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +46 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +6 -101
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +7 -2
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +76 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +73 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +208 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  146. data/lib/active_support/dependencies.rb +135 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +30 -15
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +20 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +179 -41
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +3 -0
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +62 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +134 -37
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +20 -11
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +33 -10
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +46 -13
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +101 -33
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +41 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +3 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +11 -10
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -4
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +8 -4
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +55 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +81 -35
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
data/CHANGELOG.md CHANGED
@@ -1,653 +1,571 @@
1
- ## Rails 5.1.0 (April 27, 2017) ##
1
+ ## Rails 6.1.1 (January 07, 2021) ##
2
2
 
3
- * `ActiveSupport::EventedFileUpdateChecker` no longer listens to
4
- directories outside of the application directory.
3
+ * Change `IPAddr#to_json` to match the behavior of the json gem returning the string representation
4
+ instead of the instance variables of the object.
5
5
 
6
- *radiospiel*
6
+ Before:
7
7
 
8
- * Return unmapped timezones from `country_zones`
8
+ ```ruby
9
+ IPAddr.new("127.0.0.1").to_json
10
+ # => "{\"addr\":2130706433,\"family\":2,\"mask_addr\":4294967295}"
11
+ ```
9
12
 
10
- If a country doesn't exist in the MAPPINGS hash then create a new
11
- `ActiveSupport::Timezone` instance using the supplied timezone id.
13
+ After:
12
14
 
13
- Fixes #28431.
15
+ ```ruby
16
+ IPAddr.new("127.0.0.1").to_json
17
+ # => "\"127.0.0.1\""
18
+ ```
14
19
 
15
- *Andrew White*
16
20
 
17
- * Add ActiveSupport::Deprecation::DeprecatedConstantAccessor
21
+ ## Rails 6.1.0 (December 09, 2020) ##
18
22
 
19
- Provides transparent deprecation of constants, compatible with exceptions.
20
- Example usage:
23
+ * Ensure `MemoryStore` disables compression by default. Reverts behavior of
24
+ `MemoryStore` to its prior rails `5.1` behavior.
21
25
 
22
- module Example
23
- include ActiveSupport::Deprecation::DeprecatedConstantAccessor
24
- deprecate_constant 'OldException', 'Elsewhere::NewException'
25
- end
26
+ *Max Gurewitz*
26
27
 
27
- *Dominic Cleal*
28
+ * Calling `iso8601` on negative durations retains the negative sign on individual
29
+ digits instead of prepending it.
28
30
 
29
- * Fixed bug in `DateAndTime::Compatibility#to_time` that caused it to
30
- raise `RuntimeError: can't modify frozen Time` when called on any frozen `Time`.
31
- Properly pass through the frozen `Time` or `ActiveSupport::TimeWithZone` object
32
- when calling `#to_time`.
31
+ This change is required so we can interoperate with PostgreSQL, which prefers
32
+ negative signs for each component.
33
33
 
34
- *Kevin McPhillips* & *Andrew White*
34
+ Compatibility with other iso8601 parsers which support leading negatives as well
35
+ as negatives per component is still retained.
35
36
 
36
- * Remove implicit coercion deprecation of durations
37
+ Before:
37
38
 
38
- In #28204 we deprecated implicit conversion of durations to a numeric which
39
- represented the number of seconds in the duration because of unwanted side
40
- effects with calculations on durations and dates. This unfortunately had
41
- the side effect of forcing a explicit cast when configuring third-party
42
- libraries like expiration in Redis, e.g:
39
+ (-1.year - 1.day).iso8601
40
+ # => "-P1Y1D"
43
41
 
44
- redis.expire("foo", 5.minutes)
42
+ After:
45
43
 
46
- To work around this we've removed the deprecation and added a private class
47
- that wraps the numeric and can perform calculation involving durations and
48
- ensure that they remain a duration irrespective of the order of operations.
44
+ (-1.year - 1.day).iso8601
45
+ # => "P-1Y-1D"
49
46
 
50
- *Andrew White*
47
+ *Vipul A M*
51
48
 
52
- * Update `titleize` regex to allow apostrophes
49
+ * Remove deprecated `ActiveSupport::Notifications::Instrumenter#end=`.
53
50
 
54
- In 4b685aa the regex in `titleize` was updated to not match apostrophes to
55
- better reflect the nature of the transformation. Unfortunately, this had the
56
- side effect of breaking capitalization on the first word of a sub-string, e.g:
51
+ *Rafael Mendonça França*
57
52
 
58
- >> "This was 'fake news'".titleize
59
- => "This Was 'fake News'"
53
+ * Deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
60
54
 
61
- This is fixed by extending the look-behind to also check for a word
62
- character on the other side of the apostrophe.
55
+ *Rafael Mendonça França*
63
56
 
64
- Fixes #28312.
57
+ * Remove deprecated `ActiveSupport::Multibyte::Unicode.pack_graphemes`,
58
+ `ActiveSupport::Multibyte::Unicode.unpack_graphemes`,
59
+ `ActiveSupport::Multibyte::Unicode.normalize`,
60
+ `ActiveSupport::Multibyte::Unicode.downcase`,
61
+ `ActiveSupport::Multibyte::Unicode.upcase` and `ActiveSupport::Multibyte::Unicode.swapcase`.
65
62
 
66
- *Andrew White*
63
+ *Rafael Mendonça França*
67
64
 
68
- * Add `rfc3339` aliases to `xmlschema` for `Time` and `ActiveSupport::TimeWithZone`
65
+ * Remove deprecated `ActiveSupport::Multibyte::Chars#consumes?` and `ActiveSupport::Multibyte::Chars#normalize`.
69
66
 
70
- For naming consistency when using the RFC 3339 profile of ISO 8601 in applications.
67
+ *Rafael Mendonça França*
71
68
 
72
- *Andrew White*
69
+ * Remove deprecated file `active_support/core_ext/range/include_range`.
73
70
 
74
- * Add `Time.rfc3339` parsing method
71
+ *Rafael Mendonça França*
75
72
 
76
- `Time.xmlschema` and consequently its alias `iso8601` accepts timestamps
77
- without a offset in contravention of the RFC 3339 standard. This method
78
- enforces that constraint and raises an `ArgumentError` if it doesn't.
73
+ * Remove deprecated file `active_support/core_ext/hash/transform_values`.
79
74
 
80
- *Andrew White*
75
+ *Rafael Mendonça França*
81
76
 
82
- * Add `ActiveSupport::TimeZone.rfc3339` parsing method
77
+ * Remove deprecated file `active_support/core_ext/hash/compact`.
83
78
 
84
- Previously, there was no way to get a RFC 3339 timestamp into a specific
85
- timezone without either using `parse` or chaining methods. The new method
86
- allows parsing directly into the timezone, e.g:
79
+ *Rafael Mendonça França*
87
80
 
88
- >> Time.zone = "Hawaii"
89
- => "Hawaii"
90
- >> Time.zone.rfc3339("1999-12-31T14:00:00Z")
91
- => Fri, 31 Dec 1999 14:00:00 HST -10:00
81
+ * Remove deprecated file `active_support/core_ext/array/prepend_and_append`.
92
82
 
93
- This new method has stricter semantics than the current `parse` method,
94
- and will raise an `ArgumentError` instead of returning nil, e.g:
83
+ *Rafael Mendonça França*
95
84
 
96
- >> Time.zone = "Hawaii"
97
- => "Hawaii"
98
- >> Time.zone.rfc3339("foobar")
99
- ArgumentError: invalid date
100
- >> Time.zone.parse("foobar")
101
- => nil
85
+ * Remove deprecated file `active_support/core_ext/numeric/inquiry`.
102
86
 
103
- It will also raise an `ArgumentError` when either the time or offset
104
- components are missing, e.g:
87
+ *Rafael Mendonça França*
105
88
 
106
- >> Time.zone = "Hawaii"
107
- => "Hawaii"
108
- >> Time.zone.rfc3339("1999-12-31")
109
- ArgumentError: invalid date
110
- >> Time.zone.rfc3339("1999-12-31T14:00:00")
111
- ArgumentError: invalid date
89
+ * Remove deprecated file `active_support/core_ext/module/reachable`.
112
90
 
113
- *Andrew White*
91
+ *Rafael Mendonça França*
114
92
 
115
- * Add `ActiveSupport::TimeZone.iso8601` parsing method
93
+ * Remove deprecated `Module#parent_name`, `Module#parent` and `Module#parents`.
116
94
 
117
- Previously, there was no way to get a ISO 8601 timestamp into a specific
118
- timezone without either using `parse` or chaining methods. The new method
119
- allows parsing directly into the timezone, e.g:
95
+ *Rafael Mendonça França*
120
96
 
121
- >> Time.zone = "Hawaii"
122
- => "Hawaii"
123
- >> Time.zone.iso8601("1999-12-31T14:00:00Z")
124
- => Fri, 31 Dec 1999 14:00:00 HST -10:00
97
+ * Remove deprecated `ActiveSupport::LoggerThreadSafeLevel#after_initialize`.
125
98
 
126
- If the timestamp is a ISO 8601 date (YYYY-MM-DD), then the time is set
127
- to midnight, e.g:
99
+ *Rafael Mendonça França*
128
100
 
129
- >> Time.zone = "Hawaii"
130
- => "Hawaii"
131
- >> Time.zone.iso8601("1999-12-31")
132
- => Fri, 31 Dec 1999 00:00:00 HST -10:00
101
+ * Remove deprecated `LoggerSilence` constant.
133
102
 
134
- This new method has stricter semantics than the current `parse` method,
135
- and will raise an `ArgumentError` instead of returning nil, e.g:
103
+ *Rafael Mendonça França*
136
104
 
137
- >> Time.zone = "Hawaii"
138
- => "Hawaii"
139
- >> Time.zone.iso8601("foobar")
140
- ArgumentError: invalid date
141
- >> Time.zone.parse("foobar")
142
- => nil
105
+ * Remove deprecated fallback to `I18n.default_local` when `config.i18n.fallbacks` is empty.
143
106
 
144
- *Andrew White*
107
+ *Rafael Mendonça França*
145
108
 
146
- * Deprecate implicit coercion of `ActiveSupport::Duration`
109
+ * Remove entries from local cache on `RedisCacheStore#delete_matched`
147
110
 
148
- Currently `ActiveSupport::Duration` implicitly converts to a seconds
149
- value when used in a calculation except for the explicit examples of
150
- addition and subtraction where the duration is the receiver, e.g:
111
+ Fixes #38627
151
112
 
152
- >> 2 * 1.day
153
- => 172800
113
+ *ojab*
154
114
 
155
- This results in lots of confusion especially when using durations
156
- with dates because adding/subtracting a value from a date treats
157
- integers as a day and not a second, e.g:
115
+ * Speed up `ActiveSupport::SecurityUtils.fixed_length_secure_compare` by using
116
+ `OpenSSL.fixed_length_secure_compare`, if available.
158
117
 
159
- >> Date.today
160
- => Wed, 01 Mar 2017
161
- >> Date.today + 2 * 1.day
162
- => Mon, 10 Apr 2490
118
+ *Nate Matykiewicz*
163
119
 
164
- To fix this we're implementing `coerce` so that we can provide a
165
- deprecation warning with the intent of removing the implicit coercion
166
- in Rails 5.2, e.g:
120
+ * `ActiveSupport::Cache::MemCacheStore` now checks `ENV["MEMCACHE_SERVERS"]` before falling back to `"localhost:11211"` if configured without any addresses.
167
121
 
168
- >> 2 * 1.day
169
- DEPRECATION WARNING: Implicit coercion of ActiveSupport::Duration
170
- to a Numeric is deprecated and will raise a TypeError in Rails 5.2.
171
- => 172800
122
+ ```ruby
123
+ config.cache_store = :mem_cache_store
172
124
 
173
- In Rails 5.2 it will raise `TypeError`, e.g:
125
+ # is now equivalent to
174
126
 
175
- >> 2 * 1.day
176
- TypeError: ActiveSupport::Duration can't be coerced into Integer
127
+ config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
177
128
 
178
- This is the same behavior as with other types in Ruby, e.g:
129
+ # instead of
179
130
 
180
- >> 2 * "foo"
181
- TypeError: String can't be coerced into Integer
182
- >> "foo" * 2
183
- => "foofoo"
131
+ config.cache_store = :mem_cache_store, "localhost:11211" # ignores ENV["MEMCACHE_SERVERS"]
132
+ ```
184
133
 
185
- As part of this deprecation add `*` and `/` methods to `AS::Duration`
186
- so that calculations that keep the duration as the receiver work
187
- correctly whether the final receiver is a `Date` or `Time`, e.g:
134
+ *Sam Bostock*
188
135
 
189
- >> Date.today
190
- => Wed, 01 Mar 2017
191
- >> Date.today + 1.day * 2
192
- => Fri, 03 Mar 2017
136
+ * `ActiveSupport::Subscriber#attach_to` now accepts an `inherit_all:` argument. When set to true,
137
+ it allows a subscriber to receive events for methods defined in the subscriber's ancestor class(es).
193
138
 
194
- Fixes #27457.
139
+ ```ruby
140
+ class ActionControllerSubscriber < ActiveSupport::Subscriber
141
+ attach_to :action_controller
195
142
 
196
- *Andrew White*
143
+ def start_processing(event)
144
+ info "Processing by #{event.payload[:controller]}##{event.payload[:action]} as #{format}"
145
+ end
197
146
 
198
- * Update `DateTime#change` to support `:usec` and `:nsec` options.
147
+ def redirect_to(event)
148
+ info { "Redirected to #{event.payload[:location]}" }
149
+ end
150
+ end
199
151
 
200
- Adding support for these options now allows us to update the `DateTime#end_of`
201
- methods to match the equivalent `Time#end_of` methods, e.g:
152
+ # We detach ActionControllerSubscriber from the :action_controller namespace so that our CustomActionControllerSubscriber
153
+ # can provide its own instrumentation for certain events in the namespace
154
+ ActionControllerSubscriber.detach_from(:action_controller)
202
155
 
203
- datetime = DateTime.now.end_of_day
204
- datetime.nsec == 999999999 # => true
156
+ class CustomActionControllerSubscriber < ActionControllerSubscriber
157
+ attach_to :action_controller, inherit_all: true
205
158
 
206
- Fixes #21424.
159
+ def start_processing(event)
160
+ info "A custom response to start_processing events"
161
+ end
207
162
 
208
- *Dan Moore*, *Andrew White*
163
+ # => CustomActionControllerSubscriber will process events for "start_processing.action_controller" notifications
164
+ # using its own #start_processing implementation, while retaining ActionControllerSubscriber's instrumentation
165
+ # for "redirect_to.action_controller" notifications
166
+ end
167
+ ```
209
168
 
210
- * Add `ActiveSupport::Duration#before` and `#after` as aliases for `#until` and `#since`
169
+ *Adrianna Chang*
211
170
 
212
- These read more like English and require less mental gymnastics to read and write.
171
+ * Allow the digest class used to generate non-sensitive digests to be configured with `config.active_support.hash_digest_class`.
213
172
 
214
- Before:
173
+ `config.active_support.use_sha1_digests` is deprecated in favour of `config.active_support.hash_digest_class = ::Digest::SHA1`.
215
174
 
216
- 2.weeks.since(customer_start_date)
217
- 5.days.until(today)
175
+ *Dirkjan Bussink*
218
176
 
219
- After:
177
+ * Fix bug to make memcached write_entry expire correctly with unless_exist
220
178
 
221
- 2.weeks.after(customer_start_date)
222
- 5.days.before(today)
179
+ *Jye Lee*
223
180
 
224
- *Nick Johnstone*
181
+ * Add `ActiveSupport::Duration` conversion methods
225
182
 
226
- * Soft-deprecated the top-level `HashWithIndifferentAccess` constant.
227
- `ActiveSupport::HashWithIndifferentAccess` should be used instead.
183
+ `in_seconds`, `in_minutes`, `in_hours`, `in_days`, `in_weeks`, `in_months`, and `in_years` return the respective duration covered.
228
184
 
229
- Fixes #28157.
185
+ *Jason York*
230
186
 
231
- *Robin Dupret*
187
+ * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
188
+ to `read_multi` causing `fetch_multi` to not work properly
232
189
 
233
- * In Core Extensions, make `MarshalWithAutoloading#load` pass through the second, optional
234
- argument for `Marshal#load( source [, proc] )`. This way we don't have to do
235
- `Marshal.method(:load).super_method.call(source, proc)` just to be able to pass a proc.
190
+ *Rajesh Sharma*
236
191
 
237
- *Jeff Latz*
192
+ * Fixed issue in `ActiveSupport::Cache::MemCacheStore` which caused duplicate compression,
193
+ and caused the provided `compression_threshold` to not be respected.
238
194
 
239
- * `ActiveSupport::Gzip.decompress` now checks checksum and length in footer.
195
+ *Max Gurewitz*
240
196
 
241
- *Dylan Thacker-Smith*
197
+ * Prevent `RedisCacheStore` and `MemCacheStore` from performing compression
198
+ when reading entries written with `raw: true`.
242
199
 
243
- * Cache `ActiveSupport::TimeWithZone#to_datetime` before freezing.
200
+ *Max Gurewitz*
244
201
 
245
- *Adam Rice*
202
+ * `URI.parser` is deprecated and will be removed in Rails 6.2. Use
203
+ `URI::DEFAULT_PARSER` instead.
246
204
 
247
- * Deprecate `ActiveSupport.halt_callback_chains_on_return_false`.
205
+ *Jean Boussier*
248
206
 
249
- *Rafael Mendonça França*
250
-
251
- * Remove deprecated behavior that halts callbacks when the return is false.
207
+ * `require_dependency` has been documented to be _obsolete_ in `:zeitwerk`
208
+ mode. The method is not deprecated as such (yet), but applications are
209
+ encouraged to not use it.
252
210
 
253
- *Rafael Mendonça França*
211
+ In `:zeitwerk` mode, semantics match Ruby's and you do not need to be
212
+ defensive with load order. Just refer to classes and modules normally. If
213
+ the constant name is dynamic, camelize if needed, and constantize.
254
214
 
255
- * Deprecate passing string to `:if` and `:unless` conditional options
256
- on `set_callback` and `skip_callback`.
215
+ *Xavier Noria*
257
216
 
258
- *Ryuta Kamizono*
217
+ * Add 3rd person aliases of `Symbol#start_with?` and `Symbol#end_with?`.
259
218
 
260
- * Raise `ArgumentError` when passing string to define callback.
219
+ ```ruby
220
+ :foo.starts_with?("f") # => true
221
+ :foo.ends_with?("o") # => true
222
+ ```
261
223
 
262
224
  *Ryuta Kamizono*
263
225
 
264
- * Updated Unicode version to 9.0.0
265
-
266
- Now we can handle new emojis such like "👩‍👩‍👧‍👦" ("\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}").
267
-
268
- version 8.0.0
269
-
270
- "👩‍👩‍👧‍👦".mb_chars.grapheme_length # => 4
271
- "👩‍👩‍👧‍👦".mb_chars.reverse # => "👦👧‍👩‍👩‍"
272
-
273
- version 9.0.0
274
-
275
- "👩‍👩‍👧‍👦".mb_chars.grapheme_length # => 1
276
- "👩‍👩‍👧‍👦".mb_chars.reverse # => "👩‍👩‍👧‍👦"
277
-
278
- *Fumiaki MATSUSHIMA*
226
+ * Add override of unary plus for `ActiveSupport::Duration`.
279
227
 
280
- * Changed `ActiveSupport::Inflector#transliterate` to raise `ArgumentError` when it receives
281
- anything except a string.
228
+ `+ 1.second` is now identical to `+1.second` to prevent errors
229
+ where a seemingly innocent change of formatting leads to a change in the code behavior.
282
230
 
283
- *Kevin McPhillips*
284
-
285
- * Fixed bugs that `StringInquirer#respond_to_missing?` and
286
- `ArrayInquirer#respond_to_missing?` do not fallback to `super`.
287
-
288
- *Akira Matsuda*
289
-
290
- * Fix inconsistent results when parsing large durations and constructing durations from code
291
-
292
- ActiveSupport::Duration.parse('P3Y') == 3.years # It should be true
293
-
294
- Duration parsing made independent from any moment of time:
295
- Fixed length in seconds is assigned to each duration part during parsing.
296
-
297
- Changed duration of months and years in seconds to more accurate and logical:
298
-
299
- 1. The value of 365.2425 days in Gregorian year is more accurate
300
- as it accounts for every 400th non-leap year.
231
+ Before:
232
+ ```ruby
233
+ +1.second.class
234
+ # => ActiveSupport::Duration
235
+ (+ 1.second).class
236
+ # => Integer
237
+ ```
301
238
 
302
- 2. Month's length is bound to year's duration, which makes
303
- sensible comparisons like `12.months == 1.year` to be `true`
304
- and nonsensical ones like `30.days == 1.month` to be `false`.
239
+ After:
240
+ ```ruby
241
+ +1.second.class
242
+ # => ActiveSupport::Duration
243
+ (+ 1.second).class
244
+ # => ActiveSupport::Duration
245
+ ```
305
246
 
306
- Calculations on times and dates with durations shouldn't be affected as
307
- duration's numeric value isn't used in calculations, only parts are used.
247
+ Fixes #39079.
308
248
 
309
- Methods on `Numeric` like `2.days` now use these predefined durations
310
- to avoid duplication of duration constants through the codebase and
311
- eliminate creation of intermediate durations.
249
+ *Roman Kushnir*
312
250
 
313
- *Andrey Novikov*, *Andrew White*
251
+ * Add subsec to `ActiveSupport::TimeWithZone#inspect`.
314
252
 
315
- * Change return value of `Rational#duplicable?`, `ComplexClass#duplicable?`
316
- to false.
253
+ Before:
317
254
 
318
- *utilum*
255
+ Time.at(1498099140).in_time_zone.inspect
256
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
257
+ Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
258
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
259
+ Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
260
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
319
261
 
320
- * Change return value of `NilClass#duplicable?`, `FalseClass#duplicable?`,
321
- `TrueClass#duplicable?`, `Symbol#duplicable?` and `Numeric#duplicable?`
322
- to true with Ruby 2.4+. These classes can dup with Ruby 2.4+.
262
+ After:
323
263
 
324
- *Yuji Yaginuma*
264
+ Time.at(1498099140).in_time_zone.inspect
265
+ # => "Thu, 22 Jun 2017 02:39:00.000000000 UTC +00:00"
266
+ Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
267
+ # => "Thu, 22 Jun 2017 02:39:00.123456780 UTC +00:00"
268
+ Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
269
+ # => "Thu, 22 Jun 2017 02:39:00.333333333 UTC +00:00"
325
270
 
326
- * Remove deprecated class `ActiveSupport::Concurrency::Latch`.
271
+ *akinomaeni*
327
272
 
328
- *Andrew White*
273
+ * Calling `ActiveSupport::TaggedLogging#tagged` without a block now returns a tagged logger.
329
274
 
330
- * Remove deprecated separator argument from `parameterize`.
275
+ ```ruby
276
+ logger.tagged("BCX").info("Funky time!") # => [BCX] Funky time!
277
+ ```
331
278
 
332
- *Andrew White*
279
+ *Eugene Kenny*
333
280
 
334
- * Remove deprecated method `Numeric#to_formatted_s`.
281
+ * Align `Range#cover?` extension behavior with Ruby behavior for backwards ranges.
335
282
 
336
- *Andrew White*
283
+ `(1..10).cover?(5..3)` now returns `false`, as it does in plain Ruby.
337
284
 
338
- * Remove deprecated method `alias_method_chain`.
285
+ Also update `#include?` and `#===` behavior to match.
339
286
 
340
- *Andrew White*
287
+ *Michael Groeneman*
341
288
 
342
- * Remove deprecated constant `MissingSourceFile`.
289
+ * Update to TZInfo v2.0.0.
343
290
 
344
- *Andrew White*
291
+ This changes the output of `ActiveSupport::TimeZone.utc_to_local`, but
292
+ can be controlled with the
293
+ `ActiveSupport.utc_to_local_returns_utc_offset_times` config.
345
294
 
346
- * Remove deprecated methods `Module.qualified_const_defined?`,
347
- `Module.qualified_const_get` and `Module.qualified_const_set`.
295
+ New Rails 6.1 apps have it enabled by default, existing apps can upgrade
296
+ via the config in config/initializers/new_framework_defaults_6_1.rb
348
297
 
349
- *Andrew White*
298
+ See the `utc_to_local_returns_utc_offset_times` documentation for details.
350
299
 
351
- * Remove deprecated `:prefix` option from `number_to_human_size`.
300
+ *Phil Ross*, *Jared Beck*
352
301
 
353
- *Andrew White*
302
+ * Add Date and Time `#yesterday?` and `#tomorrow?` alongside `#today?`.
354
303
 
355
- * Remove deprecated method `ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default`.
304
+ Aliased to `#prev_day?` and `#next_day?` to match the existing `#prev/next_day` methods.
356
305
 
357
- *Andrew White*
306
+ *Jatin Dhankhar*
358
307
 
359
- * Remove deprecated file `active_support/core_ext/time/marshal.rb`.
308
+ * Add `Enumerable#pick` to complement `ActiveRecord::Relation#pick`.
360
309
 
361
- *Andrew White*
310
+ *Eugene Kenny*
362
311
 
363
- * Remove deprecated file `active_support/core_ext/struct.rb`.
312
+ * [Breaking change] `ActiveSupport::Callbacks#halted_callback_hook` now receive a 2nd argument:
364
313
 
365
- *Andrew White*
314
+ `ActiveSupport::Callbacks#halted_callback_hook` now receive the name of the callback
315
+ being halted as second argument.
316
+ This change will allow you to differentiate which callbacks halted the chain
317
+ and act accordingly.
366
318
 
367
- * Remove deprecated file `active_support/core_ext/module/method_transplanting.rb`.
319
+ ```ruby
320
+ class Book < ApplicationRecord
321
+ before_save { throw(:abort) }
322
+ before_create { throw(:abort) }
368
323
 
369
- *Andrew White*
324
+ def halted_callback_hook(filter, callback_name)
325
+ Rails.logger.info("Book couldn't be #{callback_name}d")
326
+ end
370
327
 
371
- * Remove deprecated method `Module.local_constants`.
328
+ Book.create # => "Book couldn't be created"
329
+ book.save # => "Book couldn't be saved"
330
+ end
331
+ ```
372
332
 
373
- *Andrew White*
333
+ *Edouard Chin*
374
334
 
375
- * Remove deprecated file `active_support/core_ext/kernel/debugger.rb`.
335
+ * Support `prepend` with `ActiveSupport::Concern`.
376
336
 
377
- *Andrew White*
337
+ Allows a module with `extend ActiveSupport::Concern` to be prepended.
378
338
 
379
- * Remove deprecated method `ActiveSupport::Cache::Store#namespaced_key`.
339
+ module Imposter
340
+ extend ActiveSupport::Concern
380
341
 
381
- *Andrew White*
342
+ # Same as `included`, except only run when prepended.
343
+ prepended do
344
+ end
345
+ end
382
346
 
383
- * Remove deprecated method `ActiveSupport::Cache::Strategy::LocalCache::LocalStore#set_cache_value`.
347
+ class Person
348
+ prepend Imposter
349
+ end
384
350
 
385
- *Andrew White*
351
+ Class methods are prepended to the base class, concerning is also
352
+ updated: `concerning :Imposter, prepend: true do`.
386
353
 
387
- * Remove deprecated method `ActiveSupport::Cache::MemCacheStore#escape_key`.
354
+ *Jason Karns*, *Elia Schito*
388
355
 
389
- *Andrew White*
356
+ * Deprecate using `Range#include?` method to check the inclusion of a value
357
+ in a date time range. It is recommended to use `Range#cover?` method
358
+ instead of `Range#include?` to check the inclusion of a value
359
+ in a date time range.
390
360
 
391
- * Remove deprecated method `ActiveSupport::Cache::FileStore#key_file_path`.
361
+ *Vishal Telangre*
392
362
 
393
- *Andrew White*
363
+ * Support added for a `round_mode` parameter, in all number helpers. (See: `BigDecimal::mode`.)
394
364
 
395
- * Ensure duration parsing is consistent across DST changes.
365
+ ```ruby
366
+ number_to_currency(1234567890.50, precision: 0, round_mode: :half_down) # => "$1,234,567,890"
367
+ number_to_percentage(302.24398923423, precision: 5, round_mode: :down) # => "302.24398%"
368
+ number_to_rounded(389.32314, precision: 0, round_mode: :ceil) # => "390"
369
+ number_to_human_size(483989, precision: 2, round_mode: :up) # => "480 KB"
370
+ number_to_human(489939, precision: 2, round_mode: :floor) # => "480 Thousand"
396
371
 
397
- Previously `ActiveSupport::Duration.parse` used `Time.current` and
398
- `Time#advance` to calculate the number of seconds in the duration
399
- from an arbitrary collection of parts. However as `advance` tries to
400
- be consistent across DST boundaries this meant that either the
401
- duration was shorter or longer depending on the time of year.
372
+ 485000.to_s(:human, precision: 2, round_mode: :half_even) # => "480 Thousand"
373
+ ```
402
374
 
403
- This was fixed by using an absolute reference point in UTC which
404
- isn't subject to DST transitions. An arbitrary date of Jan 1st, 2000
405
- was chosen for no other reason that it seemed appropriate.
375
+ *Tom Lord*
406
376
 
407
- Additionally, duration parsing should now be marginally faster as we
408
- are no longer creating instances of `ActiveSupport::TimeWithZone`
409
- every time we parse a duration string.
377
+ * `Array#to_sentence` no longer returns a frozen string.
410
378
 
411
- Fixes #26941.
379
+ Before:
412
380
 
413
- *Andrew White*
381
+ ['one', 'two'].to_sentence.frozen?
382
+ # => true
414
383
 
415
- * Use `Hash#compact` and `Hash#compact!` from Ruby 2.4. Old Ruby versions
416
- will continue to get these methods from Active Support as before.
384
+ After:
417
385
 
418
- *Prathamesh Sonpatki*
386
+ ['one', 'two'].to_sentence.frozen?
387
+ # => false
419
388
 
420
- * Fix `ActiveSupport::TimeZone#strptime`.
421
- Support for timestamps in format of seconds (%s) and milliseconds (%Q).
389
+ *Nicolas Dular*
422
390
 
423
- Fixes #26840.
391
+ * 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.
392
+ This keeps the parser and serializer on the same page.
424
393
 
425
- *Lev Denisov*
394
+ ```ruby
395
+ duration = ActiveSupport::Duration.build(1000000)
396
+ # 1 week, 4 days, 13 hours, 46 minutes, and 40.0 seconds
426
397
 
427
- * Fix `DateAndTime::Calculations#copy_time_to`. Copy `nsec` instead of `usec`.
398
+ duration_iso = duration.iso8601
399
+ # P11DT13H46M40S
428
400
 
429
- Jumping forward or backward between weeks now preserves nanosecond digits.
401
+ ActiveSupport::Duration.parse(duration_iso)
402
+ # 11 days, 13 hours, 46 minutes, and 40 seconds
430
403
 
431
- *Josua Schmid*
404
+ duration = ActiveSupport::Duration.build(604800)
405
+ # 1 week
432
406
 
433
- * Fix `ActiveSupport::TimeWithZone#in` across DST boundaries.
407
+ duration_iso = duration.iso8601
408
+ # P1W
434
409
 
435
- Previously calls to `in` were being sent to the non-DST aware
436
- method `Time#since` via `method_missing`. It is now aliased to
437
- the DST aware `ActiveSupport::TimeWithZone#+` which handles
438
- transitions across DST boundaries, e.g:
410
+ ActiveSupport::Duration.parse(duration_iso)
411
+ # 1 week
412
+ ```
439
413
 
440
- Time.zone = "US/Eastern"
414
+ *Abhishek Sarkar*
441
415
 
442
- t = Time.zone.local(2016,11,6,1)
443
- # => Sun, 06 Nov 2016 01:00:00 EDT -05:00
416
+ * Add block support to `ActiveSupport::Testing::TimeHelpers#travel_back`.
444
417
 
445
- t.in(1.hour)
446
- # => Sun, 06 Nov 2016 01:00:00 EST -05:00
418
+ *Tim Masliuchenko*
447
419
 
448
- Fixes #26580.
420
+ * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
421
+ `ActiveSupport.parse_json_times = true`.
449
422
 
450
- *Thomas Balthazar*
423
+ *Christian Gregg*
451
424
 
452
- * Remove unused parameter `options = nil` for `#clear` of
453
- `ActiveSupport::Cache::Strategy::LocalCache::LocalStore` and
454
- `ActiveSupport::Cache::Strategy::LocalCache`.
425
+ * Support symbolic links for `content_path` in `ActiveSupport::EncryptedFile`.
455
426
 
456
- *Yosuke Kabuto*
427
+ *Takumi Shotoku*
457
428
 
458
- * Fix `thread_mattr_accessor` subclass no longer overwrites parent.
429
+ * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
430
+ and endless range targets.
459
431
 
460
- Assigning a value to a subclass using `thread_mattr_accessor` no
461
- longer changes the value of the parent class. This brings the
462
- behavior inline with the documentation.
432
+ *Allen Hsu*, *Andrew Hodgkinson*
463
433
 
464
- Given:
434
+ * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
465
435
 
466
- class Account
467
- thread_mattr_accessor :user
468
- end
436
+ *Iain Beeston*
469
437
 
470
- class Customer < Account
471
- end
438
+ * Prevent `ActiveSupport::Duration.build(value)` from creating instances of
439
+ `ActiveSupport::Duration` unless `value` is of type `Numeric`.
472
440
 
473
- Account.user = "DHH"
474
- Customer.user = "Rafael"
441
+ Addresses the errant set of behaviours described in #37012 where
442
+ `ActiveSupport::Duration` comparisons would fail confusingly
443
+ or return unexpected results when comparing durations built from instances of `String`.
475
444
 
476
445
  Before:
477
446
 
478
- Account.user # => "Rafael"
479
-
480
- After:
447
+ small_duration_from_string = ActiveSupport::Duration.build('9')
448
+ large_duration_from_string = ActiveSupport::Duration.build('100000000000000')
449
+ small_duration_from_int = ActiveSupport::Duration.build(9)
481
450
 
482
- Account.user # => "DHH"
451
+ large_duration_from_string > small_duration_from_string
452
+ # => false
483
453
 
484
- *Shinichi Maeshima*
454
+ small_duration_from_string == small_duration_from_int
455
+ # => false
485
456
 
486
- * Since weeks are no longer converted to days, add `:weeks` to the list of
487
- parts that `ActiveSupport::TimeWithZone` will recognize as possibly being
488
- of variable duration to take account of DST transitions.
457
+ small_duration_from_int < large_duration_from_string
458
+ # => ArgumentError (comparison of ActiveSupport::Duration::Scalar with ActiveSupport::Duration failed)
489
459
 
490
- Fixes #26039.
460
+ large_duration_from_string > small_duration_from_int
461
+ # => ArgumentError (comparison of String with ActiveSupport::Duration failed)
491
462
 
492
- *Andrew White*
493
-
494
- * Defines `Regexp.match?` for Ruby versions prior to 2.4. The predicate
495
- has the same interface, but it does not have the performance boost. Its
496
- purpose is to be able to write 2.4 compatible code.
497
-
498
- *Xavier Noria*
499
-
500
- * Allow `MessageEncryptor` to take advantage of authenticated encryption modes.
501
-
502
- AEAD modes like `aes-256-gcm` provide both confidentiality and data
503
- authenticity, eliminating the need to use `MessageVerifier` to check if the
504
- encrypted data has been tampered with. This speeds up encryption/decryption
505
- and results in shorter cipher text.
506
-
507
- *Bart de Water*
463
+ After:
508
464
 
509
- * Introduce `assert_changes` and `assert_no_changes`.
465
+ small_duration_from_string = ActiveSupport::Duration.build('9')
466
+ # => TypeError (can't build an ActiveSupport::Duration from a String)
510
467
 
511
- `assert_changes` is a more general `assert_difference` that works with any
512
- value.
468
+ *Alexei Emam*
513
469
 
514
- assert_changes 'Error.current', from: nil, to: 'ERR' do
515
- expected_bad_operation
516
- end
470
+ * Add `ActiveSupport::Cache::Store#delete_multi` method to delete multiple keys from the cache store.
517
471
 
518
- Can be called with strings, to be evaluated in the binding (context) of
519
- the block given to the assertion, or a lambda.
520
-
521
- assert_changes -> { Error.current }, from: nil, to: 'ERR' do
522
- expected_bad_operation
523
- end
472
+ *Peter Zhu*
524
473
 
525
- The `from` and `to` arguments are compared with the case operator (`===`).
474
+ * Support multiple arguments in `HashWithIndifferentAccess` for `merge` and `update` methods, to
475
+ follow Ruby 2.6 addition.
526
476
 
527
- assert_changes 'Error.current', from: nil, to: Error do
528
- expected_bad_operation
529
- end
477
+ *Wojciech Wnętrzak*
530
478
 
531
- This is pretty useful, if you need to loosely compare a value. For example,
532
- you need to test a token has been generated and it has that many random
533
- characters.
479
+ * Allow initializing `thread_mattr_*` attributes via `:default` option.
534
480
 
535
- user = User.start_registration
536
- assert_changes 'user.token', to: /\w{32}/ do
537
- user.finish_registration
481
+ class Scraper
482
+ thread_mattr_reader :client, default: Api::Client.new
538
483
  end
539
484
 
540
- *Genadi Samokovarov*
541
-
542
- * Fix `ActiveSupport::TimeZone#strptime`. Now raises `ArgumentError` when the
543
- given time doesn't match the format. The error is the same as the one given
544
- by Ruby's `Date.strptime`. Previously it raised
545
- `NoMethodError: undefined method empty? for nil:NilClass.` due to a bug.
485
+ *Guilherme Mansur*
546
486
 
547
- Fixes #25701.
487
+ * Add `compact_blank` for those times when you want to remove #blank? values from
488
+ an Enumerable (also `compact_blank!` on Hash, Array, ActionController::Parameters).
548
489
 
549
- *John Gesimondo*
490
+ *Dana Sherson*
550
491
 
551
- * `travel/travel_to` travel time helpers, now raise on nested calls,
552
- as this can lead to confusing time stubbing.
492
+ * Make ActiveSupport::Logger Fiber-safe.
553
493
 
554
- Instead of:
494
+ Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
495
+ to make log level local to Ruby Fibers in addition to Threads.
555
496
 
556
- travel_to 2.days.from_now do
557
- # 2 days from today
558
- travel_to 3.days.from_now do
559
- # 5 days from today
560
- end
561
- end
497
+ Example:
562
498
 
563
- preferred way to achieve above is:
499
+ logger = ActiveSupport::Logger.new(STDOUT)
500
+ logger.level = 1
501
+ puts "Main is debug? #{logger.debug?}"
564
502
 
565
- travel 2.days do
566
- # 2 days from today
567
- end
503
+ Fiber.new {
504
+ logger.local_level = 0
505
+ puts "Thread is debug? #{logger.debug?}"
506
+ }.resume
568
507
 
569
- travel 5.days do
570
- # 5 days from today
571
- end
508
+ puts "Main is debug? #{logger.debug?}"
572
509
 
573
- *Vipul A M*
574
-
575
- * Support parsing JSON time in ISO8601 local time strings in
576
- `ActiveSupport::JSON.decode` when `parse_json_times` is enabled.
577
- Strings in the format of `YYYY-MM-DD hh:mm:ss` (without a `Z` at
578
- the end) will be parsed in the local timezone (`Time.zone`). In
579
- addition, date strings (`YYYY-MM-DD`) are now parsed into `Date`
580
- objects.
581
-
582
- *Grzegorz Witek*
510
+ Before:
583
511
 
584
- * Fixed `ActiveSupport::Logger.broadcast` so that calls to `#silence` now
585
- properly delegate to all loggers. Silencing now properly suppresses logging
586
- to both the log and the console.
512
+ Main is debug? false
513
+ Thread is debug? true
514
+ Main is debug? true
587
515
 
588
- *Kevin McPhillips*
516
+ After:
589
517
 
590
- * Remove deprecated arguments in `assert_nothing_raised`.
518
+ Main is debug? false
519
+ Thread is debug? true
520
+ Main is debug? false
591
521
 
592
- *Rafel Mendonça França*
522
+ Fixes #36752.
593
523
 
594
- * `Date.to_s` doesn't produce too many spaces. For example, `to_s(:short)`
595
- will now produce `01 Feb` instead of ` 1 Feb`.
524
+ *Alexander Varnin*
596
525
 
597
- Fixes #25251.
526
+ * Allow the `on_rotation` proc used when decrypting/verifying a message to be
527
+ passed at the constructor level.
598
528
 
599
- *Sean Griffin*
529
+ Before:
600
530
 
601
- * Introduce `Module#delegate_missing_to`.
531
+ crypt = ActiveSupport::MessageEncryptor.new('long_secret')
532
+ crypt.decrypt_and_verify(encrypted_message, on_rotation: proc { ... })
533
+ crypt.decrypt_and_verify(another_encrypted_message, on_rotation: proc { ... })
602
534
 
603
- When building a decorator, a common pattern emerges:
535
+ After:
604
536
 
605
- class Partition
606
- def initialize(first_event)
607
- @events = [ first_event ]
608
- end
537
+ crypt = ActiveSupport::MessageEncryptor.new('long_secret', on_rotation: proc { ... })
538
+ crypt.decrypt_and_verify(encrypted_message)
539
+ crypt.decrypt_and_verify(another_encrypted_message)
609
540
 
610
- def people
611
- if @events.first.detail.people.any?
612
- @events.collect { |e| Array(e.detail.people) }.flatten.uniq
613
- else
614
- @events.collect(&:creator).uniq
615
- end
616
- end
541
+ *Edouard Chin*
617
542
 
618
- private
619
- def respond_to_missing?(name, include_private = false)
620
- @events.respond_to?(name, include_private)
621
- end
543
+ * `delegate_missing_to` would raise a `DelegationError` if the object
544
+ delegated to was `nil`. Now the `allow_nil` option has been added to enable
545
+ the user to specify they want `nil` returned in this case.
622
546
 
623
- def method_missing(method, *args, &block)
624
- @events.send(method, *args, &block)
625
- end
626
- end
547
+ *Matthew Tanous*
627
548
 
628
- With `Module#delegate_missing_to`, the above is condensed to:
549
+ * `truncate` would return the original string if it was too short to be truncated
550
+ and a frozen string if it were long enough to be truncated. Now truncate will
551
+ consistently return an unfrozen string regardless. This behavior is consistent
552
+ with `gsub` and `strip`.
629
553
 
630
- class Partition
631
- delegate_missing_to :@events
554
+ Before:
632
555
 
633
- def initialize(first_event)
634
- @events = [ first_event ]
635
- end
556
+ 'foobar'.truncate(5).frozen?
557
+ # => true
558
+ 'foobar'.truncate(6).frozen?
559
+ # => false
636
560
 
637
- def people
638
- if @events.first.detail.people.any?
639
- @events.collect { |e| Array(e.detail.people) }.flatten.uniq
640
- else
641
- @events.collect(&:creator).uniq
642
- end
643
- end
644
- end
561
+ After:
645
562
 
646
- *Genadi Samokovarov*, *DHH*
563
+ 'foobar'.truncate(5).frozen?
564
+ # => false
565
+ 'foobar'.truncate(6).frozen?
566
+ # => false
647
567
 
648
- * Rescuable: If a handler doesn't match the exception, check for handlers
649
- matching the exception's cause.
568
+ *Jordan Thomas*
650
569
 
651
- *Jeremy Daer*
652
570
 
653
- Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/activesupport/CHANGELOG.md) for previous changes.
571
+ Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activesupport/CHANGELOG.md) for previous changes.