activesupport 5.1.7 → 6.1.7

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