activesupport 5.2.4.4 → 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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +353 -435
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support.rb +14 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/array_inquirer.rb +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +29 -3
  9. data/lib/active_support/benchmarkable.rb +1 -1
  10. data/lib/active_support/cache.rb +142 -78
  11. data/lib/active_support/cache/file_store.rb +33 -33
  12. data/lib/active_support/cache/mem_cache_store.rb +32 -20
  13. data/lib/active_support/cache/memory_store.rb +59 -33
  14. data/lib/active_support/cache/null_store.rb +8 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +70 -43
  16. data/lib/active_support/cache/strategy/local_cache.rb +41 -26
  17. data/lib/active_support/callbacks.rb +81 -64
  18. data/lib/active_support/concern.rb +70 -3
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  20. data/lib/active_support/concurrency/share_lock.rb +0 -1
  21. data/lib/active_support/configurable.rb +10 -14
  22. data/lib/active_support/configuration_file.rb +46 -0
  23. data/lib/active_support/core_ext.rb +1 -1
  24. data/lib/active_support/core_ext/array.rb +1 -1
  25. data/lib/active_support/core_ext/array/access.rb +18 -6
  26. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/benchmark.rb +2 -2
  29. data/lib/active_support/core_ext/class/attribute.rb +32 -47
  30. data/lib/active_support/core_ext/class/subclasses.rb +17 -38
  31. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  32. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +37 -47
  34. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  35. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  36. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  38. data/lib/active_support/core_ext/enumerable.rb +171 -75
  39. data/lib/active_support/core_ext/hash.rb +1 -2
  40. data/lib/active_support/core_ext/hash/conversions.rb +3 -3
  41. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  42. data/lib/active_support/core_ext/hash/except.rb +2 -2
  43. data/lib/active_support/core_ext/hash/keys.rb +1 -30
  44. data/lib/active_support/core_ext/hash/slice.rb +6 -27
  45. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  46. data/lib/active_support/core_ext/kernel.rb +0 -1
  47. data/lib/active_support/core_ext/load_error.rb +1 -1
  48. data/lib/active_support/core_ext/marshal.rb +2 -0
  49. data/lib/active_support/core_ext/module.rb +0 -1
  50. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  51. data/lib/active_support/core_ext/module/attribute_accessors.rb +30 -39
  52. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +17 -19
  53. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  54. data/lib/active_support/core_ext/module/delegation.rb +76 -33
  55. data/lib/active_support/core_ext/module/introspection.rb +16 -15
  56. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  57. data/lib/active_support/core_ext/name_error.rb +29 -2
  58. data/lib/active_support/core_ext/numeric.rb +0 -1
  59. data/lib/active_support/core_ext/numeric/conversions.rb +129 -129
  60. data/lib/active_support/core_ext/object/blank.rb +1 -2
  61. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  62. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  63. data/lib/active_support/core_ext/object/json.rb +14 -2
  64. data/lib/active_support/core_ext/object/try.rb +17 -7
  65. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  66. data/lib/active_support/core_ext/range/compare_range.rb +34 -13
  67. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  68. data/lib/active_support/core_ext/range/each.rb +0 -1
  69. data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
  70. data/lib/active_support/core_ext/regexp.rb +8 -5
  71. data/lib/active_support/core_ext/securerandom.rb +23 -3
  72. data/lib/active_support/core_ext/string/access.rb +5 -16
  73. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  74. data/lib/active_support/core_ext/string/filters.rb +42 -1
  75. data/lib/active_support/core_ext/string/inflections.rb +45 -6
  76. data/lib/active_support/core_ext/string/inquiry.rb +1 -0
  77. data/lib/active_support/core_ext/string/multibyte.rb +6 -5
  78. data/lib/active_support/core_ext/string/output_safety.rb +70 -13
  79. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  80. data/lib/active_support/core_ext/string/strip.rb +3 -1
  81. data/lib/active_support/core_ext/symbol.rb +3 -0
  82. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  83. data/lib/active_support/core_ext/time/calculations.rb +50 -3
  84. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  85. data/lib/active_support/core_ext/uri.rb +6 -1
  86. data/lib/active_support/current_attributes.rb +15 -2
  87. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  88. data/lib/active_support/dependencies.rb +109 -34
  89. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  90. data/lib/active_support/deprecation.rb +6 -1
  91. data/lib/active_support/deprecation/behaviors.rb +16 -3
  92. data/lib/active_support/deprecation/disallowed.rb +56 -0
  93. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  94. data/lib/active_support/deprecation/method_wrappers.rb +18 -23
  95. data/lib/active_support/deprecation/proxy_wrappers.rb +29 -6
  96. data/lib/active_support/deprecation/reporting.rb +50 -7
  97. data/lib/active_support/descendants_tracker.rb +59 -9
  98. data/lib/active_support/duration.rb +90 -38
  99. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  100. data/lib/active_support/duration/iso8601_serializer.rb +18 -14
  101. data/lib/active_support/encrypted_configuration.rb +0 -4
  102. data/lib/active_support/encrypted_file.rb +22 -4
  103. data/lib/active_support/environment_inquirer.rb +20 -0
  104. data/lib/active_support/evented_file_update_checker.rb +82 -117
  105. data/lib/active_support/execution_wrapper.rb +1 -0
  106. data/lib/active_support/file_update_checker.rb +0 -1
  107. data/lib/active_support/fork_tracker.rb +62 -0
  108. data/lib/active_support/gem_version.rb +4 -4
  109. data/lib/active_support/hash_with_indifferent_access.rb +64 -41
  110. data/lib/active_support/i18n.rb +1 -0
  111. data/lib/active_support/i18n_railtie.rb +15 -8
  112. data/lib/active_support/inflector/inflections.rb +2 -7
  113. data/lib/active_support/inflector/methods.rb +49 -58
  114. data/lib/active_support/inflector/transliterate.rb +47 -18
  115. data/lib/active_support/json/decoding.rb +25 -26
  116. data/lib/active_support/json/encoding.rb +11 -3
  117. data/lib/active_support/key_generator.rb +1 -33
  118. data/lib/active_support/lazy_load_hooks.rb +5 -2
  119. data/lib/active_support/locale/en.rb +33 -0
  120. data/lib/active_support/locale/en.yml +7 -3
  121. data/lib/active_support/log_subscriber.rb +39 -9
  122. data/lib/active_support/logger.rb +2 -17
  123. data/lib/active_support/logger_silence.rb +11 -19
  124. data/lib/active_support/logger_thread_safe_level.rb +50 -6
  125. data/lib/active_support/message_encryptor.rb +8 -13
  126. data/lib/active_support/message_verifier.rb +10 -10
  127. data/lib/active_support/messages/metadata.rb +11 -2
  128. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  129. data/lib/active_support/messages/rotator.rb +10 -9
  130. data/lib/active_support/multibyte/chars.rb +10 -68
  131. data/lib/active_support/multibyte/unicode.rb +15 -327
  132. data/lib/active_support/notifications.rb +72 -8
  133. data/lib/active_support/notifications/fanout.rb +116 -16
  134. data/lib/active_support/notifications/instrumenter.rb +71 -9
  135. data/lib/active_support/number_helper.rb +38 -12
  136. data/lib/active_support/number_helper/number_converter.rb +5 -6
  137. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
  138. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  139. data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
  140. data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -3
  141. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  142. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  143. data/lib/active_support/number_helper/number_to_rounded_converter.rb +8 -7
  144. data/lib/active_support/number_helper/rounding_helper.rb +12 -28
  145. data/lib/active_support/option_merger.rb +22 -3
  146. data/lib/active_support/ordered_hash.rb +1 -1
  147. data/lib/active_support/ordered_options.rb +13 -3
  148. data/lib/active_support/parameter_filter.rb +133 -0
  149. data/lib/active_support/per_thread_registry.rb +1 -1
  150. data/lib/active_support/rails.rb +1 -10
  151. data/lib/active_support/railtie.rb +23 -1
  152. data/lib/active_support/reloader.rb +4 -5
  153. data/lib/active_support/rescuable.rb +4 -4
  154. data/lib/active_support/secure_compare_rotator.rb +51 -0
  155. data/lib/active_support/security_utils.rb +19 -12
  156. data/lib/active_support/string_inquirer.rb +4 -3
  157. data/lib/active_support/subscriber.rb +72 -28
  158. data/lib/active_support/tagged_logging.rb +42 -8
  159. data/lib/active_support/test_case.rb +91 -0
  160. data/lib/active_support/testing/assertions.rb +30 -9
  161. data/lib/active_support/testing/deprecation.rb +0 -1
  162. data/lib/active_support/testing/file_fixtures.rb +2 -0
  163. data/lib/active_support/testing/isolation.rb +2 -2
  164. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  165. data/lib/active_support/testing/parallelization.rb +51 -0
  166. data/lib/active_support/testing/parallelization/server.rb +78 -0
  167. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  168. data/lib/active_support/testing/stream.rb +1 -2
  169. data/lib/active_support/testing/time_helpers.rb +47 -12
  170. data/lib/active_support/time_with_zone.rb +81 -47
  171. data/lib/active_support/values/time_zone.rb +32 -17
  172. data/lib/active_support/xml_mini.rb +2 -10
  173. data/lib/active_support/xml_mini/jdom.rb +2 -3
  174. data/lib/active_support/xml_mini/libxml.rb +2 -2
  175. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  176. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  177. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  178. data/lib/active_support/xml_mini/rexml.rb +10 -3
  179. metadata +58 -32
  180. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
  181. data/lib/active_support/core_ext/hash/compact.rb +0 -29
  182. data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
  183. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  184. data/lib/active_support/core_ext/module/reachable.rb +0 -11
  185. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
  186. data/lib/active_support/core_ext/range/include_range.rb +0 -3
  187. data/lib/active_support/values/unicode_tables.dat +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3bb5a13385855af91f1e96d4d28fc628debd76b122cd65d16e7c40ca26a70c6
4
- data.tar.gz: 2df7294b411760b2207c7f426de1c462b3bbeeac60e9291664196115f6a07597
3
+ metadata.gz: 3d215240c46e0de60027e61d480a945128c8c07823224325caa07011fd404054
4
+ data.tar.gz: c141c31282b64aa0cb097498b73706811f5de6fb287c90fef4975fb000e6d157
5
5
  SHA512:
6
- metadata.gz: 5e3b6220c7fdbcbedfa5813ac8bc03da049e319178bcf8e0a0d37dfb698077a841515cce0fa50ccecfd3ae018840f8e6ab2b0c658f0768dffab2f3096340701f
7
- data.tar.gz: 788c51200d4d71af4975c460f5920822bb91ebe2d774c84fbd08b99048190f0c43f8b29b9a8a12c320e99e4947688fe976a3367cfa8390d047735ba0d90f83cd
6
+ metadata.gz: 9f4ac84a1eda835f117fc1c275d87772abf989cd9b51f724f373a8b148f1001135e0687262affaf3cbc4ebf82b4800e089c8c81138f538f92b654c81cd58df8a
7
+ data.tar.gz: 7209b244dccaa86cf99de2281316a12a0b308db6f4dd8b65113244fd1e879ee516d81d9ed75ab4ea7936d833e41019c6df95a2389033a5a542276c11602707ea
data/CHANGELOG.md CHANGED
@@ -1,653 +1,571 @@
1
- ## Rails 5.2.4.4 (September 09, 2020) ##
1
+ ## Rails 6.1.1 (January 07, 2021) ##
2
2
 
3
- * No changes.
4
-
5
-
6
- ## Rails 5.2.4.3 (May 18, 2020) ##
7
-
8
- * [CVE-2020-8165] Deprecate Marshal.load on raw cache read in RedisCacheStore
9
-
10
- * [CVE-2020-8165] Avoid Marshal.load on raw cache value in MemCacheStore
11
-
12
- ## Rails 5.2.4.1 (December 18, 2019) ##
13
-
14
- * No changes.
15
-
16
-
17
- ## Rails 5.2.4 (November 27, 2019) ##
18
-
19
- * Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
20
-
21
- Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
22
- to make log level local to Ruby Fibers in addition to Threads.
23
-
24
- Example:
25
-
26
- logger = ActiveSupport::Logger.new(STDOUT)
27
- logger.level = 1
28
- p "Main is debug? #{logger.debug?}"
29
-
30
- Fiber.new {
31
- logger.local_level = 0
32
- p "Thread is debug? #{logger.debug?}"
33
- }.resume
34
-
35
- p "Main is debug? #{logger.debug?}"
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.
36
5
 
37
6
  Before:
38
7
 
39
- Main is debug? false
40
- Thread is debug? true
41
- Main is debug? true
8
+ ```ruby
9
+ IPAddr.new("127.0.0.1").to_json
10
+ # => "{\"addr\":2130706433,\"family\":2,\"mask_addr\":4294967295}"
11
+ ```
42
12
 
43
13
  After:
44
14
 
45
- Main is debug? false
46
- Thread is debug? true
47
- Main is debug? false
48
-
49
- *Alexander Varnin*
50
-
51
-
52
- ## Rails 5.2.3 (March 27, 2019) ##
53
-
54
- * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
55
-
56
- `assoc` can now be called with either a string or a symbol.
57
-
58
- *Stefan Schüßler*
59
-
60
- * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
61
-
62
- *Keenan Brock*
63
-
64
- * Allow Range#=== and Range#cover? on Range
15
+ ```ruby
16
+ IPAddr.new("127.0.0.1").to_json
17
+ # => "\"127.0.0.1\""
18
+ ```
65
19
 
66
- `Range#cover?` can now accept a range argument like `Range#include?` and
67
- `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
68
- into a new file, with these two methods.
69
20
 
70
- *utilum*
21
+ ## Rails 6.1.0 (December 09, 2020) ##
71
22
 
72
- * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
23
+ * Ensure `MemoryStore` disables compression by default. Reverts behavior of
24
+ `MemoryStore` to its prior rails `5.1` behavior.
73
25
 
74
- *Mark J. Titorenko*, *Vlad Bokov*
26
+ *Max Gurewitz*
75
27
 
28
+ * Calling `iso8601` on negative durations retains the negative sign on individual
29
+ digits instead of prepending it.
76
30
 
77
- ## Rails 5.2.2.1 (March 11, 2019) ##
31
+ This change is required so we can interoperate with PostgreSQL, which prefers
32
+ negative signs for each component.
78
33
 
79
- * No changes.
34
+ Compatibility with other iso8601 parsers which support leading negatives as well
35
+ as negatives per component is still retained.
80
36
 
37
+ Before:
81
38
 
82
- ## Rails 5.2.2 (December 04, 2018) ##
39
+ (-1.year - 1.day).iso8601
40
+ # => "-P1Y1D"
83
41
 
84
- * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
85
- would not act as alias for `#symbolize_keys`.
42
+ After:
86
43
 
87
- *Nick Weiland*
44
+ (-1.year - 1.day).iso8601
45
+ # => "P-1Y-1D"
88
46
 
89
- * Improve the logic that detects non-autoloaded constants.
47
+ *Vipul A M*
90
48
 
91
- *Jan Habermann*, *Xavier Noria*
49
+ * Remove deprecated `ActiveSupport::Notifications::Instrumenter#end=`.
92
50
 
93
- * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
51
+ *Rafael Mendonça França*
94
52
 
95
- URI.unescape("\xe3\x83\x90") # => "バ"
96
- URI.unescape("%E3%83%90") # => "バ"
97
- URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
53
+ * Deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
98
54
 
99
- *Ashe Connor*, *Aaron Patterson*
55
+ *Rafael Mendonça França*
100
56
 
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`.
101
62
 
102
- ## Rails 5.2.1.1 (November 27, 2018) ##
63
+ *Rafael Mendonça França*
103
64
 
104
- * No changes.
65
+ * Remove deprecated `ActiveSupport::Multibyte::Chars#consumes?` and `ActiveSupport::Multibyte::Chars#normalize`.
105
66
 
67
+ *Rafael Mendonça França*
106
68
 
107
- ## Rails 5.2.1 (August 07, 2018) ##
69
+ * Remove deprecated file `active_support/core_ext/range/include_range`.
108
70
 
109
- * Redis cache store: `delete_matched` no longer blocks the Redis server.
110
- (Switches from evaled Lua to a batched SCAN + DEL loop.)
71
+ *Rafael Mendonça França*
111
72
 
112
- *Gleb Mazovetskiy*
73
+ * Remove deprecated file `active_support/core_ext/hash/transform_values`.
113
74
 
114
- * Fix bug where `ActiveSupport::Timezone.all` would fail when tzinfo data for
115
- any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
75
+ *Rafael Mendonça França*
116
76
 
117
- *Dominik Sander*
77
+ * Remove deprecated file `active_support/core_ext/hash/compact`.
118
78
 
119
- * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
120
- size when compression is enabled (which is true by default). This patch
121
- does not attempt to repair existing data: please manually flush the cache
122
- to clear out the problematic entries.
79
+ *Rafael Mendonça França*
123
80
 
124
- *Godfrey Chan*
81
+ * Remove deprecated file `active_support/core_ext/array/prepend_and_append`.
125
82
 
126
- * Fix `ActiveSupport::Cache#read_multi` bug with local cache enabled that was
127
- returning instances of `ActiveSupport::Cache::Entry` instead of the raw values.
83
+ *Rafael Mendonça França*
128
84
 
129
- *Jason Lee*
85
+ * Remove deprecated file `active_support/core_ext/numeric/inquiry`.
130
86
 
87
+ *Rafael Mendonça França*
131
88
 
132
- ## Rails 5.2.0 (April 09, 2018) ##
89
+ * Remove deprecated file `active_support/core_ext/module/reachable`.
133
90
 
134
- * Caching: MemCache and Redis `read_multi` and `fetch_multi` speedup.
135
- Read from the local in-memory cache before consulting the backend.
91
+ *Rafael Mendonça França*
136
92
 
137
- *Gabriel Sobrinho*
93
+ * Remove deprecated `Module#parent_name`, `Module#parent` and `Module#parents`.
138
94
 
139
- * Return all mappings for a timezone identifier in `country_zones`.
95
+ *Rafael Mendonça França*
140
96
 
141
- Some timezones like `Europe/London` have multiple mappings in
142
- `ActiveSupport::TimeZone::MAPPING` so return all of them instead
143
- of the first one found by using `Hash#value`. e.g:
97
+ * Remove deprecated `ActiveSupport::LoggerThreadSafeLevel#after_initialize`.
144
98
 
145
- # Before
146
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh"]
99
+ *Rafael Mendonça França*
147
100
 
148
- # After
149
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh", "London"]
101
+ * Remove deprecated `LoggerSilence` constant.
150
102
 
151
- Fixes #31668.
103
+ *Rafael Mendonça França*
152
104
 
153
- *Andrew White*
105
+ * Remove deprecated fallback to `I18n.default_local` when `config.i18n.fallbacks` is empty.
154
106
 
155
- * Add support for connection pooling on RedisCacheStore.
107
+ *Rafael Mendonça França*
156
108
 
157
- *fatkodima*
109
+ * Remove entries from local cache on `RedisCacheStore#delete_matched`
158
110
 
159
- * Support hash as first argument in `assert_difference`. This allows to specify multiple
160
- numeric differences in the same assertion.
111
+ Fixes #38627
161
112
 
162
- assert_difference ->{ Article.count } => 1, ->{ Post.count } => 2
113
+ *ojab*
163
114
 
164
- *Julien Meichelbeck*
115
+ * Speed up `ActiveSupport::SecurityUtils.fixed_length_secure_compare` by using
116
+ `OpenSSL.fixed_length_secure_compare`, if available.
165
117
 
166
- * Add missing instrumentation for `read_multi` in `ActiveSupport::Cache::Store`.
118
+ *Nate Matykiewicz*
167
119
 
168
- *Ignatius Reza Lesmana*
120
+ * `ActiveSupport::Cache::MemCacheStore` now checks `ENV["MEMCACHE_SERVERS"]` before falling back to `"localhost:11211"` if configured without any addresses.
169
121
 
170
- * `assert_changes` will always assert that the expression changes,
171
- regardless of `from:` and `to:` argument combinations.
122
+ ```ruby
123
+ config.cache_store = :mem_cache_store
172
124
 
173
- *Daniel Ma*
125
+ # is now equivalent to
174
126
 
175
- * Use SHA-1 to generate non-sensitive digests, such as the ETag header.
127
+ config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
176
128
 
177
- Enabled by default for new apps; upgrading apps can opt in by setting
178
- `config.active_support.use_sha1_digests = true`.
129
+ # instead of
179
130
 
180
- *Dmitri Dolguikh*, *Eugene Kenny*
131
+ config.cache_store = :mem_cache_store, "localhost:11211" # ignores ENV["MEMCACHE_SERVERS"]
132
+ ```
181
133
 
182
- * Changed default behaviour of `ActiveSupport::SecurityUtils.secure_compare`,
183
- to make it not leak length information even for variable length string.
134
+ *Sam Bostock*
184
135
 
185
- Renamed old `ActiveSupport::SecurityUtils.secure_compare` to `fixed_length_secure_compare`,
186
- and started raising `ArgumentError` in case of length mismatch of passed strings.
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).
187
138
 
188
- *Vipul A M*
139
+ ```ruby
140
+ class ActionControllerSubscriber < ActiveSupport::Subscriber
141
+ attach_to :action_controller
189
142
 
190
- * Make `ActiveSupport::TimeZone.all` return only time zones that are in
191
- `ActiveSupport::TimeZone::MAPPING`.
143
+ def start_processing(event)
144
+ info "Processing by #{event.payload[:controller]}##{event.payload[:action]} as #{format}"
145
+ end
192
146
 
193
- Fixes #7245.
147
+ def redirect_to(event)
148
+ info { "Redirected to #{event.payload[:location]}" }
149
+ end
150
+ end
194
151
 
195
- *Chris LaRose*
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)
196
155
 
197
- * MemCacheStore: Support expiring counters.
156
+ class CustomActionControllerSubscriber < ActionControllerSubscriber
157
+ attach_to :action_controller, inherit_all: true
198
158
 
199
- Pass `expires_in: [seconds]` to `#increment` and `#decrement` options
200
- to set the Memcached TTL (time-to-live) if the counter doesn't exist.
201
- If the counter exists, Memcached doesn't extend its expiry when it's
202
- incremented or decremented.
159
+ def start_processing(event)
160
+ info "A custom response to start_processing events"
161
+ end
203
162
 
204
- ```
205
- Rails.cache.increment("my_counter", 1, expires_in: 2.minutes)
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
206
167
  ```
207
168
 
208
- *Takumasa Ochi*
169
+ *Adrianna Chang*
209
170
 
210
- * Handle `TZInfo::AmbiguousTime` errors.
171
+ * Allow the digest class used to generate non-sensitive digests to be configured with `config.active_support.hash_digest_class`.
211
172
 
212
- Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous
213
- times by choosing the later period, e.g.
173
+ `config.active_support.use_sha1_digests` is deprecated in favour of `config.active_support.hash_digest_class = ::Digest::SHA1`.
214
174
 
215
- Ruby:
216
- ```
217
- ENV["TZ"] = "Europe/Moscow"
218
- Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300
219
- ```
175
+ *Dirkjan Bussink*
220
176
 
221
- Before:
222
- ```
223
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
224
- TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time.
225
- ```
226
-
227
- After:
228
- ```
229
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
230
- => Sun, 26 Oct 2014 01:00:00 MSK +03:00
231
- ```
232
-
233
- Fixes #17395.
177
+ * Fix bug to make memcached write_entry expire correctly with unless_exist
234
178
 
235
- *Andrew White*
179
+ *Jye Lee*
236
180
 
237
- * Redis cache store.
181
+ * Add `ActiveSupport::Duration` conversion methods
238
182
 
239
- ```
240
- # Defaults to `redis://localhost:6379/0`. Only use for dev/test.
241
- config.cache_store = :redis_cache_store
242
-
243
- # Supports all common cache store options (:namespace, :compress,
244
- # :compress_threshold, :expires_in, :race_condition_ttl) and all
245
- # Redis options.
246
- cache_password = Rails.application.secrets.redis_cache_password
247
- config.cache_store = :redis_cache_store, driver: :hiredis,
248
- namespace: 'myapp-cache', compress: true, timeout: 1,
249
- url: "redis://:#{cache_password}@myapp-cache-1:6379/0"
250
-
251
- # Supports Redis::Distributed with multiple hosts
252
- config.cache_store = :redis_cache_store, driver: :hiredis
253
- namespace: 'myapp-cache', compress: true,
254
- url: %w[
255
- redis://myapp-cache-1:6379/0
256
- redis://myapp-cache-1:6380/0
257
- redis://myapp-cache-2:6379/0
258
- redis://myapp-cache-2:6380/0
259
- redis://myapp-cache-3:6379/0
260
- redis://myapp-cache-3:6380/0
261
- ]
262
-
263
- # Or pass a builder block
264
- config.cache_store = :redis_cache_store,
265
- namespace: 'myapp-cache', compress: true,
266
- redis: -> { Redis.new … }
267
- ```
183
+ `in_seconds`, `in_minutes`, `in_hours`, `in_days`, `in_weeks`, `in_months`, and `in_years` return the respective duration covered.
268
184
 
269
- Deployment note: Take care to use a *dedicated Redis cache* rather
270
- than pointing this at your existing Redis server. It won't cope well
271
- with mixed usage patterns and it won't expire cache entries by default.
185
+ *Jason York*
272
186
 
273
- Redis cache server setup guide: https://redis.io/topics/lru-cache
187
+ * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
188
+ to `read_multi` causing `fetch_multi` to not work properly
274
189
 
275
- *Jeremy Daer*
190
+ *Rajesh Sharma*
276
191
 
277
- * Cache: Enable compression by default for values > 1kB.
192
+ * Fixed issue in `ActiveSupport::Cache::MemCacheStore` which caused duplicate compression,
193
+ and caused the provided `compression_threshold` to not be respected.
278
194
 
279
- Compression has long been available, but opt-in and at a 16kB threshold.
280
- It wasn't enabled by default due to CPU cost. Today it's cheap and typical
281
- cache data is eminently compressible, such as HTML or JSON fragments.
282
- Compression dramatically reduces Memcached/Redis mem usage, which means
283
- the same cache servers can store more data, which means higher hit rates.
195
+ *Max Gurewitz*
284
196
 
285
- To disable compression, pass `compress: false` to the initializer.
197
+ * Prevent `RedisCacheStore` and `MemCacheStore` from performing compression
198
+ when reading entries written with `raw: true`.
286
199
 
287
- *Jeremy Daer*
200
+ *Max Gurewitz*
288
201
 
289
- * Allow `Range#include?` on TWZ ranges.
202
+ * `URI.parser` is deprecated and will be removed in Rails 6.2. Use
203
+ `URI::DEFAULT_PARSER` instead.
290
204
 
291
- In #11474 we prevented TWZ ranges being iterated over which matched
292
- Ruby's handling of Time ranges and as a consequence `include?`
293
- stopped working with both Time ranges and TWZ ranges. However in
294
- ruby/ruby@b061634 support was added for `include?` to use `cover?`
295
- for 'linear' objects. Since we have no way of making Ruby consider
296
- TWZ instances as 'linear' we have to override `Range#include?`.
205
+ *Jean Boussier*
297
206
 
298
- Fixes #30799.
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.
299
210
 
300
- *Andrew White*
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.
301
214
 
302
- * Fix acronym support in `humanize`.
215
+ *Xavier Noria*
303
216
 
304
- Acronym inflections are stored with lowercase keys in the hash but
305
- the match wasn't being lowercased before being looked up in the hash.
306
- This shouldn't have any performance impact because before it would
307
- fail to find the acronym and perform the `downcase` operation anyway.
217
+ * Add 3rd person aliases of `Symbol#start_with?` and `Symbol#end_with?`.
308
218
 
309
- Fixes #31052.
219
+ ```ruby
220
+ :foo.starts_with?("f") # => true
221
+ :foo.ends_with?("o") # => true
222
+ ```
310
223
 
311
- *Andrew White*
224
+ *Ryuta Kamizono*
312
225
 
313
- * Add same method signature for `Time#prev_year` and `Time#next_year`
314
- in accordance with `Date#prev_year`, `Date#next_year`.
226
+ * Add override of unary plus for `ActiveSupport::Duration`.
315
227
 
316
- Allows pass argument for `Time#prev_year` and `Time#next_year`.
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.
317
230
 
318
231
  Before:
319
- ```
320
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
321
- Time.new(2017, 9, 16, 17, 0).prev_year(1)
322
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
323
-
324
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
325
- Time.new(2017, 9, 16, 17, 0).next_year(1)
326
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
232
+ ```ruby
233
+ +1.second.class
234
+ # => ActiveSupport::Duration
235
+ (+ 1.second).class
236
+ # => Integer
327
237
  ```
328
238
 
329
239
  After:
330
- ```
331
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
332
- Time.new(2017, 9, 16, 17, 0).prev_year(1) # => 2016-09-16 17:00:00 +0300
333
-
334
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
335
- Time.new(2017, 9, 16, 17, 0).next_year(1) # => 2018-09-16 17:00:00 +0300
240
+ ```ruby
241
+ +1.second.class
242
+ # => ActiveSupport::Duration
243
+ (+ 1.second).class
244
+ # => ActiveSupport::Duration
336
245
  ```
337
246
 
338
- *bogdanvlviv*
247
+ Fixes #39079.
339
248
 
340
- * Add same method signature for `Time#prev_month` and `Time#next_month`
341
- in accordance with `Date#prev_month`, `Date#next_month`.
249
+ *Roman Kushnir*
342
250
 
343
- Allows pass argument for `Time#prev_month` and `Time#next_month`.
251
+ * Add subsec to `ActiveSupport::TimeWithZone#inspect`.
344
252
 
345
253
  Before:
346
- ```
347
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
348
- Time.new(2017, 9, 16, 17, 0).prev_month(1)
349
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
350
254
 
351
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
352
- Time.new(2017, 9, 16, 17, 0).next_month(1)
353
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
354
- ```
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"
355
261
 
356
262
  After:
357
- ```
358
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
359
- Time.new(2017, 9, 16, 17, 0).prev_month(1) # => 2017-08-16 17:00:00 +0300
360
-
361
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
362
- Time.new(2017, 9, 16, 17, 0).next_month(1) # => 2017-10-16 17:00:00 +0300
363
- ```
364
263
 
365
- *bogdanvlviv*
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"
366
270
 
367
- * Add same method signature for `Time#prev_day` and `Time#next_day`
368
- in accordance with `Date#prev_day`, `Date#next_day`.
271
+ *akinomaeni*
369
272
 
370
- Allows pass argument for `Time#prev_day` and `Time#next_day`.
273
+ * Calling `ActiveSupport::TaggedLogging#tagged` without a block now returns a tagged logger.
371
274
 
372
- Before:
275
+ ```ruby
276
+ logger.tagged("BCX").info("Funky time!") # => [BCX] Funky time!
373
277
  ```
374
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
375
- Time.new(2017, 9, 16, 17, 0).prev_day(1)
376
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
377
278
 
378
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
379
- Time.new(2017, 9, 16, 17, 0).next_day(1)
380
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
381
- ```
279
+ *Eugene Kenny*
382
280
 
383
- After:
384
- ```
385
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
386
- Time.new(2017, 9, 16, 17, 0).prev_day(1) # => 2017-09-15 17:00:00 +0300
281
+ * Align `Range#cover?` extension behavior with Ruby behavior for backwards ranges.
387
282
 
388
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
389
- Time.new(2017, 9, 16, 17, 0).next_day(1) # => 2017-09-17 17:00:00 +0300
390
- ```
391
-
392
- *bogdanvlviv*
283
+ `(1..10).cover?(5..3)` now returns `false`, as it does in plain Ruby.
393
284
 
394
- * `IO#to_json` now returns the `to_s` representation, rather than
395
- attempting to convert to an array. This fixes a bug where `IO#to_json`
396
- would raise an `IOError` when called on an unreadable object.
285
+ Also update `#include?` and `#===` behavior to match.
397
286
 
398
- Fixes #26132.
287
+ *Michael Groeneman*
399
288
 
400
- *Paul Kuruvilla*
289
+ * Update to TZInfo v2.0.0.
401
290
 
402
- * Remove deprecated `halt_callback_chains_on_return_false` option.
403
-
404
- *Rafael Mendonça França*
405
-
406
- * Remove deprecated `:if` and `:unless` string filter for callbacks.
407
-
408
- *Rafael Mendonça França*
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.
409
294
 
410
- * `Hash#slice` now falls back to Ruby 2.5+'s built-in definition if defined.
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
411
297
 
412
- *Akira Matsuda*
298
+ See the `utc_to_local_returns_utc_offset_times` documentation for details.
413
299
 
414
- * Deprecate `secrets.secret_token`.
300
+ *Phil Ross*, *Jared Beck*
415
301
 
416
- The architecture for secrets had a big upgrade between Rails 3 and Rails 4,
417
- when the default changed from using `secret_token` to `secret_key_base`.
302
+ * Add Date and Time `#yesterday?` and `#tomorrow?` alongside `#today?`.
418
303
 
419
- `secret_token` has been soft deprecated in documentation for four years
420
- but is still in place to support apps created before Rails 4.
421
- Deprecation warnings have been added to help developers upgrade their
422
- applications to `secret_key_base`.
304
+ Aliased to `#prev_day?` and `#next_day?` to match the existing `#prev/next_day` methods.
423
305
 
424
- *claudiob*, *Kasper Timm Hansen*
306
+ *Jatin Dhankhar*
425
307
 
426
- * Return an instance of `HashWithIndifferentAccess` from `HashWithIndifferentAccess#transform_keys`.
308
+ * Add `Enumerable#pick` to complement `ActiveRecord::Relation#pick`.
427
309
 
428
- *Yuji Yaginuma*
310
+ *Eugene Kenny*
429
311
 
430
- * Add key rotation support to `MessageEncryptor` and `MessageVerifier`.
312
+ * [Breaking change] `ActiveSupport::Callbacks#halted_callback_hook` now receive a 2nd argument:
431
313
 
432
- This change introduces a `rotate` method to both the `MessageEncryptor` and
433
- `MessageVerifier` classes. This method accepts the same arguments and
434
- options as the given classes' constructor. The `encrypt_and_verify` method
435
- for `MessageEncryptor` and the `verified` method for `MessageVerifier` also
436
- accept an optional keyword argument `:on_rotation` block which is called
437
- when a rotated instance is used to decrypt or verify the message.
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.
438
318
 
439
- *Michael J Coyne*
319
+ ```ruby
320
+ class Book < ApplicationRecord
321
+ before_save { throw(:abort) }
322
+ before_create { throw(:abort) }
440
323
 
441
- * Deprecate `Module#reachable?` method.
324
+ def halted_callback_hook(filter, callback_name)
325
+ Rails.logger.info("Book couldn't be #{callback_name}d")
326
+ end
442
327
 
443
- *bogdanvlviv*
328
+ Book.create # => "Book couldn't be created"
329
+ book.save # => "Book couldn't be saved"
330
+ end
331
+ ```
444
332
 
445
- * Add `config/credentials.yml.enc` to store production app secrets.
333
+ *Edouard Chin*
446
334
 
447
- Allows saving any authentication credentials for third party services
448
- directly in repo encrypted with `config/master.key` or `ENV["RAILS_MASTER_KEY"]`.
335
+ * Support `prepend` with `ActiveSupport::Concern`.
449
336
 
450
- This will eventually replace `Rails.application.secrets` and the encrypted
451
- secrets introduced in Rails 5.1.
337
+ Allows a module with `extend ActiveSupport::Concern` to be prepended.
452
338
 
453
- *DHH*, *Kasper Timm Hansen*
339
+ module Imposter
340
+ extend ActiveSupport::Concern
454
341
 
455
- * Add `ActiveSupport::EncryptedFile` and `ActiveSupport::EncryptedConfiguration`.
342
+ # Same as `included`, except only run when prepended.
343
+ prepended do
344
+ end
345
+ end
456
346
 
457
- Allows for stashing encrypted files or configuration directly in repo by
458
- encrypting it with a key.
347
+ class Person
348
+ prepend Imposter
349
+ end
459
350
 
460
- Backs the new credentials setup above, but can also be used independently.
351
+ Class methods are prepended to the base class, concerning is also
352
+ updated: `concerning :Imposter, prepend: true do`.
461
353
 
462
- *DHH*, *Kasper Timm Hansen*
354
+ *Jason Karns*, *Elia Schito*
463
355
 
464
- * `Module#delegate_missing_to` now raises `DelegationError` if target is nil,
465
- similar to `Module#delegate`.
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.
466
360
 
467
- *Anton Khamets*
361
+ *Vishal Telangre*
468
362
 
469
- * Update `String#camelize` to provide feedback when wrong option is passed.
363
+ * Support added for a `round_mode` parameter, in all number helpers. (See: `BigDecimal::mode`.)
470
364
 
471
- `String#camelize` was returning nil without any feedback when an
472
- invalid option was passed as a parameter.
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"
473
371
 
474
- Previously:
372
+ 485000.to_s(:human, precision: 2, round_mode: :half_even) # => "480 Thousand"
373
+ ```
475
374
 
476
- 'one_two'.camelize(true)
477
- # => nil
375
+ *Tom Lord*
478
376
 
479
- Now:
377
+ * `Array#to_sentence` no longer returns a frozen string.
480
378
 
481
- 'one_two'.camelize(true)
482
- # => ArgumentError: Invalid option, use either :upper or :lower.
379
+ Before:
483
380
 
484
- *Ricardo Díaz*
381
+ ['one', 'two'].to_sentence.frozen?
382
+ # => true
485
383
 
486
- * Fix modulo operations involving durations.
384
+ After:
487
385
 
488
- Rails 5.1 introduced `ActiveSupport::Duration::Scalar` as a wrapper
489
- around numeric values as a way of ensuring a duration was the outcome of
490
- an expression. However, the implementation was missing support for modulo
491
- operations. This support has now been added and should result in a duration
492
- being returned from expressions involving modulo operations.
386
+ ['one', 'two'].to_sentence.frozen?
387
+ # => false
493
388
 
494
- Prior to Rails 5.1:
389
+ *Nicolas Dular*
495
390
 
496
- 5.minutes % 2.minutes
497
- # => 60
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.
498
393
 
499
- Now:
394
+ ```ruby
395
+ duration = ActiveSupport::Duration.build(1000000)
396
+ # 1 week, 4 days, 13 hours, 46 minutes, and 40.0 seconds
500
397
 
501
- 5.minutes % 2.minutes
502
- # => 1 minute
398
+ duration_iso = duration.iso8601
399
+ # P11DT13H46M40S
503
400
 
504
- Fixes #29603 and #29743.
401
+ ActiveSupport::Duration.parse(duration_iso)
402
+ # 11 days, 13 hours, 46 minutes, and 40 seconds
505
403
 
506
- *Sayan Chakraborty*, *Andrew White*
404
+ duration = ActiveSupport::Duration.build(604800)
405
+ # 1 week
507
406
 
508
- * Fix division where a duration is the denominator.
407
+ duration_iso = duration.iso8601
408
+ # P1W
509
409
 
510
- PR #29163 introduced a change in behavior when a duration was the denominator
511
- in a calculation - this was incorrect as dividing by a duration should always
512
- return a `Numeric`. The behavior of previous versions of Rails has been restored.
410
+ ActiveSupport::Duration.parse(duration_iso)
411
+ # 1 week
412
+ ```
513
413
 
514
- Fixes #29592.
414
+ *Abhishek Sarkar*
515
415
 
516
- *Andrew White*
416
+ * Add block support to `ActiveSupport::Testing::TimeHelpers#travel_back`.
517
417
 
518
- * Add purpose and expiry support to `ActiveSupport::MessageVerifier` and
519
- `ActiveSupport::MessageEncryptor`.
418
+ *Tim Masliuchenko*
520
419
 
521
- For instance, to ensure a message is only usable for one intended purpose:
420
+ * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
421
+ `ActiveSupport.parse_json_times = true`.
522
422
 
523
- token = @verifier.generate("x", purpose: :shipping)
423
+ *Christian Gregg*
524
424
 
525
- @verifier.verified(token, purpose: :shipping) # => "x"
526
- @verifier.verified(token) # => nil
425
+ * Support symbolic links for `content_path` in `ActiveSupport::EncryptedFile`.
527
426
 
528
- Or make it expire after a set time:
427
+ *Takumi Shotoku*
529
428
 
530
- @verifier.generate("x", expires_in: 1.month)
531
- @verifier.generate("y", expires_at: Time.now.end_of_year)
429
+ * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
430
+ and endless range targets.
532
431
 
533
- Showcased with `ActiveSupport::MessageVerifier`, but works the same for
534
- `ActiveSupport::MessageEncryptor`'s `encrypt_and_sign` and `decrypt_and_verify`.
432
+ *Allen Hsu*, *Andrew Hodgkinson*
535
433
 
536
- Pull requests: #29599, #29854
434
+ * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
537
435
 
538
- *Assain Jaleel*
436
+ *Iain Beeston*
539
437
 
540
- * Make the order of `Hash#reverse_merge!` consistent with `HashWithIndifferentAccess`.
438
+ * Prevent `ActiveSupport::Duration.build(value)` from creating instances of
439
+ `ActiveSupport::Duration` unless `value` is of type `Numeric`.
541
440
 
542
- *Erol Fornoles*
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`.
543
444
 
544
- * Add `freeze_time` helper which freezes time to `Time.now` in tests.
445
+ Before:
545
446
 
546
- *Prathamesh Sonpatki*
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)
547
450
 
548
- * Default `ActiveSupport::MessageEncryptor` to use AES 256 GCM encryption.
451
+ large_duration_from_string > small_duration_from_string
452
+ # => false
549
453
 
550
- On for new Rails 5.2 apps. Upgrading apps can find the config as a new
551
- framework default.
454
+ small_duration_from_string == small_duration_from_int
455
+ # => false
552
456
 
553
- *Assain Jaleel*
457
+ small_duration_from_int < large_duration_from_string
458
+ # => ArgumentError (comparison of ActiveSupport::Duration::Scalar with ActiveSupport::Duration failed)
554
459
 
555
- * Cache: `write_multi`.
460
+ large_duration_from_string > small_duration_from_int
461
+ # => ArgumentError (comparison of String with ActiveSupport::Duration failed)
556
462
 
557
- Rails.cache.write_multi foo: 'bar', baz: 'qux'
463
+ After:
558
464
 
559
- Plus faster fetch_multi with stores that implement `write_multi_entries`.
560
- Keys that aren't found may be written to the cache store in one shot
561
- instead of separate writes.
465
+ small_duration_from_string = ActiveSupport::Duration.build('9')
466
+ # => TypeError (can't build an ActiveSupport::Duration from a String)
562
467
 
563
- The default implementation simply calls `write_entry` for each entry.
564
- Stores may override if they're capable of one-shot bulk writes, like
565
- Redis `MSET`.
468
+ *Alexei Emam*
566
469
 
567
- *Jeremy Daer*
470
+ * Add `ActiveSupport::Cache::Store#delete_multi` method to delete multiple keys from the cache store.
568
471
 
569
- * Add default option to module and class attribute accessors.
472
+ *Peter Zhu*
570
473
 
571
- mattr_accessor :settings, default: {}
474
+ * Support multiple arguments in `HashWithIndifferentAccess` for `merge` and `update` methods, to
475
+ follow Ruby 2.6 addition.
572
476
 
573
- Works for `mattr_reader`, `mattr_writer`, `cattr_accessor`, `cattr_reader`,
574
- and `cattr_writer` as well.
477
+ *Wojciech Wnętrzak*
575
478
 
576
- *Genadi Samokovarov*
479
+ * Allow initializing `thread_mattr_*` attributes via `:default` option.
577
480
 
578
- * Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
481
+ class Scraper
482
+ thread_mattr_reader :client, default: Api::Client.new
483
+ end
579
484
 
580
- *Shota Iguchi*
485
+ *Guilherme Mansur*
581
486
 
582
- * Add default option to `class_attribute`.
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).
583
489
 
584
- Before:
490
+ *Dana Sherson*
585
491
 
586
- class_attribute :settings
587
- self.settings = {}
492
+ * Make ActiveSupport::Logger Fiber-safe.
588
493
 
589
- Now:
590
-
591
- class_attribute :settings, default: {}
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.
592
496
 
593
- *DHH*
497
+ Example:
594
498
 
595
- * `#singularize` and `#pluralize` now respect uncountables for the specified locale.
499
+ logger = ActiveSupport::Logger.new(STDOUT)
500
+ logger.level = 1
501
+ puts "Main is debug? #{logger.debug?}"
596
502
 
597
- *Eilis Hamilton*
503
+ Fiber.new {
504
+ logger.local_level = 0
505
+ puts "Thread is debug? #{logger.debug?}"
506
+ }.resume
598
507
 
599
- * Add `ActiveSupport::CurrentAttributes` to provide a thread-isolated attributes singleton.
600
- Primary use case is keeping all the per-request attributes easily available to the whole system.
508
+ puts "Main is debug? #{logger.debug?}"
601
509
 
602
- *DHH*
510
+ Before:
603
511
 
604
- * Fix implicit coercion calculations with scalars and durations.
512
+ Main is debug? false
513
+ Thread is debug? true
514
+ Main is debug? true
605
515
 
606
- Previously, calculations where the scalar is first would be converted to a duration
607
- of seconds, but this causes issues with dates being converted to times, e.g:
516
+ After:
608
517
 
609
- Time.zone = "Beijing" # => Asia/Shanghai
610
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
611
- 2 * 1.day # => 172800 seconds
612
- date + 2 * 1.day # => Mon, 22 May 2017 00:00:00 CST +08:00
518
+ Main is debug? false
519
+ Thread is debug? true
520
+ Main is debug? false
613
521
 
614
- Now, the `ActiveSupport::Duration::Scalar` calculation methods will try to maintain
615
- the part structure of the duration where possible, e.g:
522
+ Fixes #36752.
616
523
 
617
- Time.zone = "Beijing" # => Asia/Shanghai
618
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
619
- 2 * 1.day # => 2 days
620
- date + 2 * 1.day # => Mon, 22 May 2017
524
+ *Alexander Varnin*
621
525
 
622
- Fixes #29160, #28970.
526
+ * Allow the `on_rotation` proc used when decrypting/verifying a message to be
527
+ passed at the constructor level.
623
528
 
624
- *Andrew White*
529
+ Before:
625
530
 
626
- * Add support for versioned cache entries. This enables the cache stores to recycle cache keys, greatly saving
627
- on storage in cases with frequent churn. Works together with the separation of `#cache_key` and `#cache_version`
628
- in Active Record and its use in Action Pack's fragment caching.
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 { ... })
629
534
 
630
- *DHH*
535
+ After:
631
536
 
632
- * Pass gem name and deprecation horizon to deprecation notifications.
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)
633
540
 
634
- *Willem van Bergen*
541
+ *Edouard Chin*
635
542
 
636
- * Add support for `:offset` and `:zone` to `ActiveSupport::TimeWithZone#change`.
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.
637
546
 
638
- *Andrew White*
547
+ *Matthew Tanous*
639
548
 
640
- * Add support for `:offset` to `Time#change`.
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`.
641
553
 
642
- Fixes #28723.
554
+ Before:
643
555
 
644
- *Andrew White*
556
+ 'foobar'.truncate(5).frozen?
557
+ # => true
558
+ 'foobar'.truncate(6).frozen?
559
+ # => false
645
560
 
646
- * Add `fetch_values` for `HashWithIndifferentAccess`.
561
+ After:
647
562
 
648
- The method was originally added to `Hash` in Ruby 2.3.0.
563
+ 'foobar'.truncate(5).frozen?
564
+ # => false
565
+ 'foobar'.truncate(6).frozen?
566
+ # => false
649
567
 
650
- *Josh Pencheon*
568
+ *Jordan Thomas*
651
569
 
652
570
 
653
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-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.