activesupport 5.2.0 → 6.1.0

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