activesupport 5.2.8 → 6.0.6.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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +476 -409
  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/backtrace_cleaner.rb +27 -1
  7. data/lib/active_support/cache/file_store.rb +32 -32
  8. data/lib/active_support/cache/mem_cache_store.rb +12 -7
  9. data/lib/active_support/cache/memory_store.rb +15 -9
  10. data/lib/active_support/cache/null_store.rb +8 -3
  11. data/lib/active_support/cache/redis_cache_store.rb +47 -20
  12. data/lib/active_support/cache/strategy/local_cache.rb +22 -22
  13. data/lib/active_support/cache.rb +71 -48
  14. data/lib/active_support/callbacks.rb +16 -8
  15. data/lib/active_support/concern.rb +24 -1
  16. data/lib/active_support/concurrency/share_lock.rb +0 -1
  17. data/lib/active_support/configurable.rb +7 -11
  18. data/lib/active_support/core_ext/array/access.rb +18 -6
  19. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  20. data/lib/active_support/core_ext/array/extract.rb +21 -0
  21. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  22. data/lib/active_support/core_ext/array.rb +1 -1
  23. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  24. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  25. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  26. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  27. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  28. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  29. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  30. data/lib/active_support/core_ext/enumerable.rb +97 -73
  31. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  32. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  33. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  34. data/lib/active_support/core_ext/hash/except.rb +2 -2
  35. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  36. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  37. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  38. data/lib/active_support/core_ext/hash.rb +1 -2
  39. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  40. data/lib/active_support/core_ext/kernel.rb +0 -1
  41. data/lib/active_support/core_ext/load_error.rb +1 -1
  42. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  43. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  44. data/lib/active_support/core_ext/module/delegation.rb +41 -8
  45. data/lib/active_support/core_ext/module/introspection.rb +38 -13
  46. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  47. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  48. data/lib/active_support/core_ext/module.rb +0 -1
  49. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  50. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  51. data/lib/active_support/core_ext/numeric.rb +0 -1
  52. data/lib/active_support/core_ext/object/blank.rb +1 -2
  53. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  54. data/lib/active_support/core_ext/object/json.rb +2 -1
  55. data/lib/active_support/core_ext/object/try.rb +17 -7
  56. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  57. data/lib/active_support/core_ext/range/compare_range.rb +28 -13
  58. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  59. data/lib/active_support/core_ext/range/each.rb +0 -1
  60. data/lib/active_support/core_ext/range/include_range.rb +6 -0
  61. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  62. data/lib/active_support/core_ext/regexp.rb +0 -4
  63. data/lib/active_support/core_ext/securerandom.rb +23 -3
  64. data/lib/active_support/core_ext/string/access.rb +8 -0
  65. data/lib/active_support/core_ext/string/filters.rb +42 -1
  66. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  67. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  68. data/lib/active_support/core_ext/string/output_safety.rb +68 -10
  69. data/lib/active_support/core_ext/string/strip.rb +3 -1
  70. data/lib/active_support/core_ext/time/calculations.rb +34 -3
  71. data/lib/active_support/core_ext/uri.rb +1 -0
  72. data/lib/active_support/current_attributes.rb +8 -0
  73. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  74. data/lib/active_support/dependencies.rb +74 -18
  75. data/lib/active_support/deprecation/behaviors.rb +1 -1
  76. data/lib/active_support/deprecation/method_wrappers.rb +17 -23
  77. data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
  78. data/lib/active_support/deprecation.rb +1 -1
  79. data/lib/active_support/descendants_tracker.rb +55 -9
  80. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  81. data/lib/active_support/duration/iso8601_serializer.rb +3 -5
  82. data/lib/active_support/duration.rb +7 -8
  83. data/lib/active_support/encrypted_configuration.rb +0 -4
  84. data/lib/active_support/encrypted_file.rb +3 -2
  85. data/lib/active_support/evented_file_update_checker.rb +39 -10
  86. data/lib/active_support/execution_wrapper.rb +2 -1
  87. data/lib/active_support/file_update_checker.rb +0 -1
  88. data/lib/active_support/gem_version.rb +4 -4
  89. data/lib/active_support/hash_with_indifferent_access.rb +22 -18
  90. data/lib/active_support/i18n.rb +1 -0
  91. data/lib/active_support/i18n_railtie.rb +13 -1
  92. data/lib/active_support/inflector/inflections.rb +1 -5
  93. data/lib/active_support/inflector/methods.rb +16 -29
  94. data/lib/active_support/inflector/transliterate.rb +47 -18
  95. data/lib/active_support/json/decoding.rb +23 -24
  96. data/lib/active_support/json/encoding.rb +6 -2
  97. data/lib/active_support/key_generator.rb +0 -32
  98. data/lib/active_support/lazy_load_hooks.rb +5 -2
  99. data/lib/active_support/locale/en.rb +33 -0
  100. data/lib/active_support/log_subscriber.rb +31 -9
  101. data/lib/active_support/logger.rb +1 -16
  102. data/lib/active_support/logger_silence.rb +28 -12
  103. data/lib/active_support/logger_thread_safe_level.rb +26 -4
  104. data/lib/active_support/message_encryptor.rb +4 -6
  105. data/lib/active_support/message_verifier.rb +5 -5
  106. data/lib/active_support/messages/metadata.rb +11 -2
  107. data/lib/active_support/messages/rotator.rb +4 -4
  108. data/lib/active_support/multibyte/chars.rb +29 -49
  109. data/lib/active_support/multibyte/unicode.rb +44 -282
  110. data/lib/active_support/notifications/fanout.rb +98 -13
  111. data/lib/active_support/notifications/instrumenter.rb +80 -9
  112. data/lib/active_support/notifications.rb +41 -4
  113. data/lib/active_support/number_helper/number_converter.rb +4 -5
  114. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
  115. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  116. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
  117. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
  118. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  119. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  120. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
  121. data/lib/active_support/number_helper/rounding_helper.rb +1 -1
  122. data/lib/active_support/number_helper.rb +11 -0
  123. data/lib/active_support/option_merger.rb +21 -3
  124. data/lib/active_support/ordered_hash.rb +1 -1
  125. data/lib/active_support/ordered_options.rb +5 -1
  126. data/lib/active_support/parameter_filter.rb +128 -0
  127. data/lib/active_support/rails.rb +0 -6
  128. data/lib/active_support/reloader.rb +4 -5
  129. data/lib/active_support/security_utils.rb +1 -1
  130. data/lib/active_support/string_inquirer.rb +0 -1
  131. data/lib/active_support/subscriber.rb +65 -26
  132. data/lib/active_support/tagged_logging.rb +13 -4
  133. data/lib/active_support/test_case.rb +91 -0
  134. data/lib/active_support/testing/assertions.rb +15 -1
  135. data/lib/active_support/testing/deprecation.rb +0 -1
  136. data/lib/active_support/testing/file_fixtures.rb +2 -0
  137. data/lib/active_support/testing/isolation.rb +2 -2
  138. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  139. data/lib/active_support/testing/parallelization.rb +134 -0
  140. data/lib/active_support/testing/stream.rb +1 -2
  141. data/lib/active_support/testing/time_helpers.rb +7 -9
  142. data/lib/active_support/time_with_zone.rb +15 -5
  143. data/lib/active_support/values/time_zone.rb +12 -7
  144. data/lib/active_support/xml_mini/jdom.rb +2 -3
  145. data/lib/active_support/xml_mini/libxml.rb +2 -2
  146. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  147. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  148. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  149. data/lib/active_support/xml_mini/rexml.rb +2 -2
  150. data/lib/active_support/xml_mini.rb +2 -10
  151. data/lib/active_support.rb +2 -1
  152. metadata +41 -12
  153. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  154. data/lib/active_support/values/unicode_tables.dat +0 -0
data/CHANGELOG.md CHANGED
@@ -1,9 +1,24 @@
1
- ## Rails 5.2.8 (May 09, 2022) ##
1
+ ## Rails 6.0.6.1 (January 17, 2023) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 5.2.7.1 (April 26, 2022) ##
6
+ ## Rails 6.0.6 (September 09, 2022) ##
7
+
8
+ * No changes.
9
+
10
+
11
+ ## Rails 6.0.5.1 (July 12, 2022) ##
12
+
13
+ * No changes.
14
+
15
+
16
+ ## Rails 6.0.5 (May 09, 2022) ##
17
+
18
+ * No changes.
19
+
20
+
21
+ ## Rails 6.0.4.8 (April 26, 2022) ##
7
22
 
8
23
  * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
9
24
 
@@ -13,70 +28,190 @@
13
28
  *Álvaro Martín Fraguas*
14
29
 
15
30
 
16
- ## Rails 5.2.7 (March 10, 2022) ##
31
+ ## Rails 6.0.4.7 (March 08, 2022) ##
32
+
33
+ * No changes.
34
+
17
35
 
18
- * Restore support to Ruby 2.2.
36
+ ## Rails 6.0.4.6 (February 11, 2022) ##
19
37
 
20
- *ojab*
38
+ * Fix Reloader method signature to work with the new Executor signature
21
39
 
22
40
 
23
- ## Rails 5.2.6.3 (March 08, 2022) ##
41
+ ## Rails 6.0.4.5 (February 11, 2022) ##
24
42
 
25
43
  * No changes.
26
44
 
27
45
 
28
- ## Rails 5.2.6.2 (February 11, 2022) ##
46
+ ## Rails 6.0.4.4 (December 15, 2021) ##
29
47
 
30
- * Fix Reloader method signature to work with the new Executor signature
48
+ * No changes.
49
+
50
+
51
+ ## Rails 6.0.4.3 (December 14, 2021) ##
52
+
53
+ * No changes.
54
+
55
+
56
+ ## Rails 6.0.4.2 (December 14, 2021) ##
57
+
58
+ * No changes.
59
+
60
+
61
+ ## Rails 6.0.4.1 (August 19, 2021) ##
31
62
 
63
+ * No changes.
64
+
65
+
66
+ ## Rails 6.0.4 (June 15, 2021) ##
67
+
68
+ * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
69
+ to `read_multi` causing `fetch_multi` to not work properly.
70
+
71
+ *Rajesh Sharma*
72
+
73
+ * `with_options` copies its options hash again to avoid leaking mutations.
74
+
75
+ Fixes #39343.
32
76
 
33
- ## Rails 5.2.6.1 (February 11, 2022) ##
77
+ *Eugene Kenny*
78
+
79
+
80
+ ## Rails 6.0.3.7 (May 05, 2021) ##
34
81
 
35
82
  * No changes.
36
83
 
37
84
 
38
- ## Rails 5.2.6 (May 05, 2021) ##
85
+ ## Rails 6.0.3.6 (March 26, 2021) ##
39
86
 
40
87
  * No changes.
41
88
 
42
89
 
43
- ## Rails 5.2.5 (March 26, 2021) ##
90
+ ## Rails 6.0.3.5 (February 10, 2021) ##
44
91
 
45
92
  * No changes.
46
93
 
47
94
 
48
- ## Rails 5.2.4.6 (May 05, 2021) ##
95
+ ## Rails 6.0.3.4 (October 07, 2020) ##
49
96
 
50
97
  * No changes.
51
98
 
52
99
 
53
- ## Rails 5.2.4.5 (February 10, 2021) ##
100
+ ## Rails 6.0.3.3 (September 09, 2020) ##
54
101
 
55
102
  * No changes.
56
103
 
57
104
 
58
- ## Rails 5.2.4.4 (September 09, 2020) ##
105
+ ## Rails 6.0.3.2 (June 17, 2020) ##
59
106
 
60
107
  * No changes.
61
108
 
62
109
 
63
- ## Rails 5.2.4.3 (May 18, 2020) ##
110
+ ## Rails 6.0.3.1 (May 18, 2020) ##
64
111
 
65
112
  * [CVE-2020-8165] Deprecate Marshal.load on raw cache read in RedisCacheStore
66
113
 
67
114
  * [CVE-2020-8165] Avoid Marshal.load on raw cache value in MemCacheStore
68
115
 
69
- ## Rails 5.2.4.2 (March 19, 2020) ##
116
+
117
+ ## Rails 6.0.3 (May 06, 2020) ##
118
+
119
+ * `Array#to_sentence` no longer returns a frozen string.
120
+
121
+ Before:
122
+
123
+ ['one', 'two'].to_sentence.frozen?
124
+ # => true
125
+
126
+ After:
127
+
128
+ ['one', 'two'].to_sentence.frozen?
129
+ # => false
130
+
131
+ *Nicolas Dular*
132
+
133
+ * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
134
+ `ActiveSupport.parse_json_times = true`.
135
+
136
+ *Christian Gregg*
137
+
138
+
139
+ ## Rails 6.0.2.2 (March 19, 2020) ##
70
140
 
71
141
  * No changes.
72
142
 
73
143
 
74
- ## Rails 5.2.4.1 (December 18, 2019) ##
144
+ ## Rails 6.0.2.1 (December 18, 2019) ##
75
145
 
76
146
  * No changes.
77
147
 
78
148
 
79
- ## Rails 5.2.4 (November 27, 2019) ##
149
+ ## Rails 6.0.2 (December 13, 2019) ##
150
+
151
+ * Eager load translations during initialization.
152
+
153
+ *Diego Plentz*
154
+
155
+ * Use per-thread CPU time clock on `ActiveSupport::Notifications`.
156
+
157
+ *George Claghorn*
158
+
159
+
160
+ ## Rails 6.0.1 (November 5, 2019) ##
161
+
162
+ * `ActiveSupport::SafeBuffer` supports `Enumerator` methods.
163
+
164
+ *Shugo Maeda*
165
+
166
+ * The Redis cache store fails gracefully when the server returns a "max number
167
+ of clients reached" error.
168
+
169
+ *Brandon Medenwald*
170
+
171
+ * Fixed that mutating a value returned by a memory cache store would
172
+ unexpectedly change the cached value.
173
+
174
+ *Jonathan Hyman*
175
+
176
+ * The default inflectors in `zeitwerk` mode support overrides:
177
+
178
+ ```ruby
179
+ # config/initializers/zeitwerk.rb
180
+ Rails.autoloaders.each do |autoloader|
181
+ autoloader.inflector.inflect(
182
+ "html_parser" => "HTMLParser",
183
+ "ssl_error" => "SSLError"
184
+ )
185
+ end
186
+ ```
187
+
188
+ That way, you can tweak how individual basenames are inflected without touching Active Support inflection rules, which are global. These inflectors fallback to `String#camelize`, so existing inflection rules are still taken into account for non-overridden basenames.
189
+
190
+ Please, check the [autoloading guide for `zeitwerk` mode](https://guides.rubyonrails.org/v6.0/autoloading_and_reloading_constants.html#customizing-inflections) if you prefer not to depend on `String#camelize` at all.
191
+
192
+ *Xavier Noria*
193
+
194
+ * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
195
+ and endless range targets.
196
+
197
+ *Allen Hsu*, *Andrew Hodgkinson*
198
+
199
+ * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
200
+
201
+ *Iain Beeston*
202
+
203
+
204
+ ## Rails 6.0.0 (August 16, 2019) ##
205
+
206
+ * Let `require_dependency` in `zeitwerk` mode look the autoload paths up for
207
+ better backwards compatibility.
208
+
209
+ *Xavier Noria*
210
+
211
+ * Let `require_dependency` in `zeitwerk` mode support arguments that respond
212
+ to `to_path` for better backwards compatibility.
213
+
214
+ *Xavier Noria*
80
215
 
81
216
  * Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
82
217
 
@@ -110,606 +245,538 @@
110
245
 
111
246
  *Alexander Varnin*
112
247
 
248
+ * Do not delegate missing `marshal_dump` and `_dump` methods via the
249
+ `delegate_missing_to` extension. This avoids unintentionally adding instance
250
+ variables when calling `Marshal.dump(object)`, should the delegation target of
251
+ `object` be a method which would otherwise add them. Fixes #36522.
113
252
 
114
- ## Rails 5.2.3 (March 27, 2019) ##
253
+ *Aaron Lipman*
115
254
 
116
- * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
117
255
 
118
- `assoc` can now be called with either a string or a symbol.
256
+ ## Rails 6.0.0.rc2 (July 22, 2019) ##
119
257
 
120
- *Stefan Schüßler*
258
+ * `truncate` would return the original string if it was too short to be truncated
259
+ and a frozen string if it were long enough to be truncated. Now truncate will
260
+ consistently return an unfrozen string regardless. This behavior is consistent
261
+ with `gsub` and `strip`.
121
262
 
122
- * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
263
+ Before:
123
264
 
124
- *Keenan Brock*
265
+ 'foobar'.truncate(5).frozen?
266
+ # => true
267
+ 'foobar'.truncate(6).frozen?
268
+ # => false
125
269
 
126
- * Allow Range#=== and Range#cover? on Range
270
+ After:
127
271
 
128
- `Range#cover?` can now accept a range argument like `Range#include?` and
129
- `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
130
- into a new file, with these two methods.
272
+ 'foobar'.truncate(5).frozen?
273
+ # => false
274
+ 'foobar'.truncate(6).frozen?
275
+ # => false
131
276
 
132
- *utilum*
277
+ *Jordan Thomas*
133
278
 
134
- * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
135
279
 
136
- *Mark J. Titorenko*, *Vlad Bokov*
280
+ ## Rails 6.0.0.rc1 (April 24, 2019) ##
137
281
 
282
+ * Speed improvements to `Hash.except` and `HashWithIndifferentAccess#except`.
138
283
 
139
- ## Rails 5.2.2.1 (March 11, 2019) ##
284
+ These methods now unset the `default`/`default_proc` on the returned Hash, compatible with Ruby 3.0’s native implementation.
140
285
 
141
- * No changes.
286
+ *Timo Schilling*
142
287
 
288
+ * Introduce `ActiveSupport::ActionableError`.
143
289
 
144
- ## Rails 5.2.2 (December 04, 2018) ##
290
+ Actionable errors let's you dispatch actions from Rails' error pages. This
291
+ can help you save time if you have a clear action for the resolution of
292
+ common development errors.
145
293
 
146
- * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
147
- would not act as alias for `#symbolize_keys`.
294
+ The de-facto example are pending migrations. Every time pending migrations
295
+ are found, a middleware raises an error. With actionable errors, you can
296
+ run the migrations right from the error page. Other examples include Rails
297
+ plugins that need to run a rake task to setup themselves. They can now
298
+ raise actionable errors to run the setup straight from the error pages.
148
299
 
149
- *Nick Weiland*
300
+ Here is how to define an actionable error:
150
301
 
151
- * Improve the logic that detects non-autoloaded constants.
302
+ ```ruby
303
+ class PendingMigrationError < MigrationError #:nodoc:
304
+ include ActiveSupport::ActionableError
152
305
 
153
- *Jan Habermann*, *Xavier Noria*
306
+ action "Run pending migrations" do
307
+ ActiveRecord::Tasks::DatabaseTasks.migrate
308
+ end
309
+ end
310
+ ```
154
311
 
155
- * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
312
+ To make an error actionable, include the `ActiveSupport::ActionableError`
313
+ module and invoke the `action` class macro to define the action. An action
314
+ needs a name and a procedure to execute. The name is shown as the name of a
315
+ button on the error pages. Once clicked, it will invoke the given
316
+ procedure.
156
317
 
157
- URI.unescape("\xe3\x83\x90") # => "バ"
158
- URI.unescape("%E3%83%90") # => "バ"
159
- URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
318
+ *Vipul A M*, *Yao Jie*, *Genadi Samokovarov*
160
319
 
161
- *Ashe Connor*, *Aaron Patterson*
320
+ * Preserve `html_safe?` status on `ActiveSupport::SafeBuffer#*`.
162
321
 
322
+ Before:
163
323
 
164
- ## Rails 5.2.1.1 (November 27, 2018) ##
324
+ ("<br />".html_safe * 2).html_safe? #=> nil
165
325
 
166
- * No changes.
326
+ After:
167
327
 
328
+ ("<br />".html_safe * 2).html_safe? #=> true
168
329
 
169
- ## Rails 5.2.1 (August 07, 2018) ##
330
+ *Ryo Nakamura*
170
331
 
171
- * Redis cache store: `delete_matched` no longer blocks the Redis server.
172
- (Switches from evaled Lua to a batched SCAN + DEL loop.)
332
+ * Calling test methods with `with_info_handler` method to allow minitest-hooks
333
+ plugin to work.
173
334
 
174
- *Gleb Mazovetskiy*
335
+ *Mauri Mustonen*
175
336
 
176
- * Fix bug where `ActiveSupport::Timezone.all` would fail when tzinfo data for
177
- any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
337
+ * The Zeitwerk compatibility interface for `ActiveSupport::Dependencies` no
338
+ longer implements `autoloaded_constants` or `autoloaded?` (undocumented,
339
+ anyway). Experience shows introspection does not have many use cases, and
340
+ troubleshooting is done by logging. With this design trade-off we are able
341
+ to use even less memory in all environments.
178
342
 
179
- *Dominik Sander*
343
+ *Xavier Noria*
180
344
 
181
- * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
182
- size when compression is enabled (which is true by default). This patch
183
- does not attempt to repair existing data: please manually flush the cache
184
- to clear out the problematic entries.
345
+ * Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
346
+ and hence uses less memory when `config.cache_classes` is `true`, a standard
347
+ setup in production.
185
348
 
186
- *Godfrey Chan*
349
+ *Xavier Noria*
187
350
 
188
- * Fix `ActiveSupport::Cache#read_multi` bug with local cache enabled that was
189
- returning instances of `ActiveSupport::Cache::Entry` instead of the raw values.
351
+ * In `:zeitwerk` mode, eager load directories in engines and applications only
352
+ if present in their respective `config.eager_load_paths`.
190
353
 
191
- *Jason Lee*
354
+ A common use case for this is adding `lib` to `config.autoload_paths`, but
355
+ not to `config.eager_load_paths`. In that configuration, for example, files
356
+ in the `lib` directory should not be eager loaded.
192
357
 
358
+ *Xavier Noria*
193
359
 
194
- ## Rails 5.2.0 (April 09, 2018) ##
360
+ * Fix bug in Range comparisons when comparing to an excluded-end Range
195
361
 
196
- * Caching: MemCache and Redis `read_multi` and `fetch_multi` speedup.
197
- Read from the local in-memory cache before consulting the backend.
362
+ Before:
198
363
 
199
- *Gabriel Sobrinho*
364
+ (1..10).cover?(1...11) # => false
200
365
 
201
- * Return all mappings for a timezone identifier in `country_zones`.
366
+ After:
202
367
 
203
- Some timezones like `Europe/London` have multiple mappings in
204
- `ActiveSupport::TimeZone::MAPPING` so return all of them instead
205
- of the first one found by using `Hash#value`. e.g:
368
+ (1..10).cover?(1...11) # => true
206
369
 
207
- # Before
208
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh"]
370
+ With the same change for `Range#include?` and `Range#===`.
209
371
 
210
- # After
211
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh", "London"]
372
+ *Owen Stephens*
212
373
 
213
- Fixes #31668.
374
+ * Use weak references in descendants tracker to allow anonymous subclasses to
375
+ be garbage collected.
214
376
 
215
- *Andrew White*
377
+ *Edgars Beigarts*
216
378
 
217
- * Add support for connection pooling on RedisCacheStore.
379
+ * Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
380
+ passing a block optional. This will let users use
381
+ `ActiveSupport::Notifications` messaging features outside of
382
+ instrumentation.
218
383
 
219
- *fatkodima*
384
+ *Ali Ibrahim*
220
385
 
221
- * Support hash as first argument in `assert_difference`. This allows to specify multiple
222
- numeric differences in the same assertion.
386
+ * Fix `Time#advance` to work with dates before 1001-03-07
223
387
 
224
- assert_difference ->{ Article.count } => 1, ->{ Post.count } => 2
388
+ Before:
225
389
 
226
- *Julien Meichelbeck*
390
+ Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
227
391
 
228
- * Add missing instrumentation for `read_multi` in `ActiveSupport::Cache::Store`.
392
+ After
229
393
 
230
- *Ignatius Reza Lesmana*
394
+ Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC
231
395
 
232
- * `assert_changes` will always assert that the expression changes,
233
- regardless of `from:` and `to:` argument combinations.
396
+ Note that this doesn't affect `DateTime#advance` as that doesn't use a proleptic calendar.
234
397
 
235
- *Daniel Ma*
398
+ *Andrew White*
236
399
 
237
- * Use SHA-1 to generate non-sensitive digests, such as the ETag header.
400
+ * In Zeitwerk mode, engines are now managed by the `main` autoloader. Engines may reference application constants, if the application is reloaded and we do not reload engines, they won't use the reloaded application code.
238
401
 
239
- Enabled by default for new apps; upgrading apps can opt in by setting
240
- `config.active_support.use_sha1_digests = true`.
402
+ *Xavier Noria*
241
403
 
242
- *Dmitri Dolguikh*, *Eugene Kenny*
404
+ * Add support for supplying `locale` to `transliterate` and `parameterize`.
243
405
 
244
- * Changed default behaviour of `ActiveSupport::SecurityUtils.secure_compare`,
245
- to make it not leak length information even for variable length string.
406
+ I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })
246
407
 
247
- Renamed old `ActiveSupport::SecurityUtils.secure_compare` to `fixed_length_secure_compare`,
248
- and started raising `ArgumentError` in case of length mismatch of passed strings.
408
+ ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
409
+ "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
410
+ ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
249
411
 
250
- *Vipul A M*
412
+ *Kaan Ozkan*, *Sharang Dashputre*
251
413
 
252
- * Make `ActiveSupport::TimeZone.all` return only time zones that are in
253
- `ActiveSupport::TimeZone::MAPPING`.
414
+ * Allow `Array#excluding` and `Enumerable#excluding` to deal with a passed array gracefully.
254
415
 
255
- Fixes #7245.
416
+ [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
256
417
 
257
- *Chris LaRose*
418
+ *DHH*
258
419
 
259
- * MemCacheStore: Support expiring counters.
420
+ * Renamed `Array#without` and `Enumerable#without` to `Array#excluding` and `Enumerable#excluding`, to create parity with
421
+ `Array#including` and `Enumerable#including`. Retained the old names as aliases.
260
422
 
261
- Pass `expires_in: [seconds]` to `#increment` and `#decrement` options
262
- to set the Memcached TTL (time-to-live) if the counter doesn't exist.
263
- If the counter exists, Memcached doesn't extend its expiry when it's
264
- incremented or decremented.
423
+ *DHH*
265
424
 
266
- ```
267
- Rails.cache.increment("my_counter", 1, expires_in: 2.minutes)
268
- ```
425
+ * Added `Array#including` and `Enumerable#including` to conveniently enlarge a collection with more members using a method rather than an operator:
269
426
 
270
- *Takumasa Ochi*
427
+ [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
428
+ post.authors.including(Current.person) # => All the authors plus the current person!
271
429
 
272
- * Handle `TZInfo::AmbiguousTime` errors.
430
+ *DHH*
273
431
 
274
- Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous
275
- times by choosing the later period, e.g.
276
432
 
277
- Ruby:
278
- ```
279
- ENV["TZ"] = "Europe/Moscow"
280
- Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300
281
- ```
433
+ ## Rails 6.0.0.beta3 (March 11, 2019) ##
282
434
 
283
- Before:
284
- ```
285
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
286
- TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time.
287
- ```
435
+ * No changes.
288
436
 
289
- After:
290
- ```
291
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
292
- => Sun, 26 Oct 2014 01:00:00 MSK +03:00
293
- ```
294
437
 
295
- Fixes #17395.
438
+ ## Rails 6.0.0.beta2 (February 25, 2019) ##
296
439
 
297
- *Andrew White*
440
+ * New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).
298
441
 
299
- * Redis cache store.
442
+ *Xavier Noria*
300
443
 
301
- ```
302
- # Defaults to `redis://localhost:6379/0`. Only use for dev/test.
303
- config.cache_store = :redis_cache_store
304
-
305
- # Supports all common cache store options (:namespace, :compress,
306
- # :compress_threshold, :expires_in, :race_condition_ttl) and all
307
- # Redis options.
308
- cache_password = Rails.application.secrets.redis_cache_password
309
- config.cache_store = :redis_cache_store, driver: :hiredis,
310
- namespace: 'myapp-cache', compress: true, timeout: 1,
311
- url: "redis://:#{cache_password}@myapp-cache-1:6379/0"
312
-
313
- # Supports Redis::Distributed with multiple hosts
314
- config.cache_store = :redis_cache_store, driver: :hiredis
315
- namespace: 'myapp-cache', compress: true,
316
- url: %w[
317
- redis://myapp-cache-1:6379/0
318
- redis://myapp-cache-1:6380/0
319
- redis://myapp-cache-2:6379/0
320
- redis://myapp-cache-2:6380/0
321
- redis://myapp-cache-3:6379/0
322
- redis://myapp-cache-3:6380/0
323
- ]
324
-
325
- # Or pass a builder block
326
- config.cache_store = :redis_cache_store,
327
- namespace: 'myapp-cache', compress: true,
328
- redis: -> { Redis.new … }
329
- ```
444
+ * Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.
330
445
 
331
- Deployment note: Take care to use a *dedicated Redis cache* rather
332
- than pointing this at your existing Redis server. It won't cope well
333
- with mixed usage patterns and it won't expire cache entries by default.
446
+ *Zach Kemp*
334
447
 
335
- Redis cache server setup guide: https://redis.io/topics/lru-cache
448
+ * Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.
336
449
 
337
- *Jeremy Daer*
338
-
339
- * Cache: Enable compression by default for values > 1kB.
450
+ *Rosa Gutierrez*
340
451
 
341
- Compression has long been available, but opt-in and at a 16kB threshold.
342
- It wasn't enabled by default due to CPU cost. Today it's cheap and typical
343
- cache data is eminently compressible, such as HTML or JSON fragments.
344
- Compression dramatically reduces Memcached/Redis mem usage, which means
345
- the same cache servers can store more data, which means higher hit rates.
452
+ * Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
346
453
 
347
- To disable compression, pass `compress: false` to the initializer.
348
-
349
- *Jeremy Daer*
454
+ *Akinori Musha*
350
455
 
351
- * Allow `Range#include?` on TWZ ranges.
456
+ * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
352
457
 
353
- In #11474 we prevented TWZ ranges being iterated over which matched
354
- Ruby's handling of Time ranges and as a consequence `include?`
355
- stopped working with both Time ranges and TWZ ranges. However in
356
- ruby/ruby@b061634 support was added for `include?` to use `cover?`
357
- for 'linear' objects. Since we have no way of making Ruby consider
358
- TWZ instances as 'linear' we have to override `Range#include?`.
458
+ `assoc` can now be called with either a string or a symbol.
359
459
 
360
- Fixes #30799.
460
+ *Stefan Schüßler*
361
461
 
362
- *Andrew White*
462
+ * Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.
363
463
 
364
- * Fix acronym support in `humanize`.
464
+ *Guillermo Iguaran*
365
465
 
366
- Acronym inflections are stored with lowercase keys in the hash but
367
- the match wasn't being lowercased before being looked up in the hash.
368
- This shouldn't have any performance impact because before it would
369
- fail to find the acronym and perform the `downcase` operation anyway.
370
466
 
371
- Fixes #31052.
467
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
372
468
 
373
- *Andrew White*
469
+ * Remove deprecated `Module#reachable?` method.
374
470
 
375
- * Add same method signature for `Time#prev_year` and `Time#next_year`
376
- in accordance with `Date#prev_year`, `Date#next_year`.
471
+ *Rafael Mendonça França*
377
472
 
378
- Allows pass argument for `Time#prev_year` and `Time#next_year`.
473
+ * Remove deprecated `#acronym_regex` method from `Inflections`.
379
474
 
380
- Before:
381
- ```
382
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
383
- Time.new(2017, 9, 16, 17, 0).prev_year(1)
384
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
475
+ *Rafael Mendonça França*
385
476
 
386
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
387
- Time.new(2017, 9, 16, 17, 0).next_year(1)
388
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
389
- ```
477
+ * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
390
478
 
391
- After:
392
- ```
393
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
394
- Time.new(2017, 9, 16, 17, 0).prev_year(1) # => 2016-09-16 17:00:00 +0300
479
+ *Keenan Brock*
395
480
 
396
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
397
- Time.new(2017, 9, 16, 17, 0).next_year(1) # => 2018-09-16 17:00:00 +0300
398
- ```
481
+ * Preserve key order passed to `ActiveSupport::CacheStore#fetch_multi`.
399
482
 
400
- *bogdanvlviv*
483
+ `fetch_multi(*names)` now returns its results in the same order as the `*names` requested, rather than returning cache hits followed by cache misses.
401
484
 
402
- * Add same method signature for `Time#prev_month` and `Time#next_month`
403
- in accordance with `Date#prev_month`, `Date#next_month`.
485
+ *Gannon McGibbon*
404
486
 
405
- Allows pass argument for `Time#prev_month` and `Time#next_month`.
487
+ * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
406
488
 
407
- Before:
408
- ```
409
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
410
- Time.new(2017, 9, 16, 17, 0).prev_month(1)
411
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
489
+ *Mark J. Titorenko*, *Vlad Bokov*
412
490
 
413
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
414
- Time.new(2017, 9, 16, 17, 0).next_month(1)
415
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
416
- ```
491
+ * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
492
+ would not act as alias for `#symbolize_keys`.
417
493
 
418
- After:
419
- ```
420
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
421
- Time.new(2017, 9, 16, 17, 0).prev_month(1) # => 2017-08-16 17:00:00 +0300
494
+ *Nick Weiland*
422
495
 
423
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
424
- Time.new(2017, 9, 16, 17, 0).next_month(1) # => 2017-10-16 17:00:00 +0300
425
- ```
496
+ * Improve the logic that detects non-autoloaded constants.
426
497
 
427
- *bogdanvlviv*
498
+ *Jan Habermann*, *Xavier Noria*
428
499
 
429
- * Add same method signature for `Time#prev_day` and `Time#next_day`
430
- in accordance with `Date#prev_day`, `Date#next_day`.
500
+ * Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` and `ActiveSupport::Multibyte::Unicode#unpack_graphemes(string)`
501
+ in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively.
431
502
 
432
- Allows pass argument for `Time#prev_day` and `Time#next_day`.
503
+ *Francesco Rodríguez*
433
504
 
434
- Before:
435
- ```
436
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
437
- Time.new(2017, 9, 16, 17, 0).prev_day(1)
438
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
505
+ * Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.
439
506
 
440
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
441
- Time.new(2017, 9, 16, 17, 0).next_day(1)
442
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
443
- ```
507
+ *Francesco Rodríguez*
444
508
 
445
- After:
509
+ * Fix duration being rounded to a full second.
446
510
  ```
447
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
448
- Time.new(2017, 9, 16, 17, 0).prev_day(1) # => 2017-09-15 17:00:00 +0300
449
-
450
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
451
- Time.new(2017, 9, 16, 17, 0).next_day(1) # => 2017-09-17 17:00:00 +0300
511
+ time = DateTime.parse("2018-1-1")
512
+ time += 0.51.seconds
452
513
  ```
514
+ Will now correctly add 0.51 second and not 1 full second.
453
515
 
454
- *bogdanvlviv*
455
-
456
- * `IO#to_json` now returns the `to_s` representation, rather than
457
- attempting to convert to an array. This fixes a bug where `IO#to_json`
458
- would raise an `IOError` when called on an unreadable object.
516
+ *Edouard Chin*
459
517
 
460
- Fixes #26132.
518
+ * Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSupport::Multibyte::Chars#normalize`
519
+ in favor of `String#unicode_normalize`
461
520
 
462
- *Paul Kuruvilla*
521
+ *Francesco Rodríguez*
463
522
 
464
- * Remove deprecated `halt_callback_chains_on_return_false` option.
523
+ * Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
524
+ `String#downcase/upcase/swapcase`.
465
525
 
466
- *Rafael Mendonça França*
467
-
468
- * Remove deprecated `:if` and `:unless` string filter for callbacks.
469
-
470
- *Rafael Mendonça França*
471
-
472
- * `Hash#slice` now falls back to Ruby 2.5+'s built-in definition if defined.
473
-
474
- *Akira Matsuda*
475
-
476
- * Deprecate `secrets.secret_token`.
526
+ *Francesco Rodríguez*
477
527
 
478
- The architecture for secrets had a big upgrade between Rails 3 and Rails 4,
479
- when the default changed from using `secret_token` to `secret_key_base`.
528
+ * Add `ActiveSupport::ParameterFilter`.
480
529
 
481
- `secret_token` has been soft deprecated in documentation for four years
482
- but is still in place to support apps created before Rails 4.
483
- Deprecation warnings have been added to help developers upgrade their
484
- applications to `secret_key_base`.
530
+ *Yoshiyuki Kinjo*
485
531
 
486
- *claudiob*, *Kasper Timm Hansen*
532
+ * Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
533
+ `module_parent`, `module_parents`, and `module_parent_name`.
487
534
 
488
- * Return an instance of `HashWithIndifferentAccess` from `HashWithIndifferentAccess#transform_keys`.
535
+ *Gannon McGibbon*
489
536
 
490
- *Yuji Yaginuma*
537
+ * Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`
491
538
 
492
- * Add key rotation support to `MessageEncryptor` and `MessageVerifier`.
539
+ *Edouard Chin*
493
540
 
494
- This change introduces a `rotate` method to both the `MessageEncryptor` and
495
- `MessageVerifier` classes. This method accepts the same arguments and
496
- options as the given classes' constructor. The `encrypt_and_verify` method
497
- for `MessageEncryptor` and the `verified` method for `MessageVerifier` also
498
- accept an optional keyword argument `:on_rotation` block which is called
499
- when a rotated instance is used to decrypt or verify the message.
541
+ * Deprecate using negative limits in `String#first` and `String#last`.
500
542
 
501
- *Michael J Coyne*
543
+ *Gannon McGibbon*, *Eric Turner*
502
544
 
503
- * Deprecate `Module#reachable?` method.
545
+ * Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
546
+ with symbol arguments
504
547
 
505
- *bogdanvlviv*
506
-
507
- * Add `config/credentials.yml.enc` to store production app secrets.
548
+ *Abraham Chan*
508
549
 
509
- Allows saving any authentication credentials for third party services
510
- directly in repo encrypted with `config/master.key` or `ENV["RAILS_MASTER_KEY"]`.
550
+ * Treat `#delete_prefix`, `#delete_suffix` and `#unicode_normalize` results as non-`html_safe`.
551
+ Ensure safety of arguments for `#insert`, `#[]=` and `#replace` calls on `html_safe` Strings.
511
552
 
512
- This will eventually replace `Rails.application.secrets` and the encrypted
513
- secrets introduced in Rails 5.1.
553
+ *Janosch Müller*
514
554
 
515
- *DHH*, *Kasper Timm Hansen*
555
+ * Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
556
+ of mutating the one received as parameter.
516
557
 
517
- * Add `ActiveSupport::EncryptedFile` and `ActiveSupport::EncryptedConfiguration`.
558
+ *Thierry Joyal*
518
559
 
519
- Allows for stashing encrypted files or configuration directly in repo by
520
- encrypting it with a key.
560
+ * Define `unfreeze_time` as an alias of `travel_back` in `ActiveSupport::Testing::TimeHelpers`.
521
561
 
522
- Backs the new credentials setup above, but can also be used independently.
562
+ The alias is provided for symmetry with `freeze_time`.
523
563
 
524
- *DHH*, *Kasper Timm Hansen*
564
+ *Ryan Davidson*
525
565
 
526
- * `Module#delegate_missing_to` now raises `DelegationError` if target is nil,
527
- similar to `Module#delegate`.
566
+ * Add support for tracing constant autoloads. Just throw
528
567
 
529
- *Anton Khamets*
568
+ ActiveSupport::Dependencies.logger = Rails.logger
569
+ ActiveSupport::Dependencies.verbose = true
530
570
 
531
- * Update `String#camelize` to provide feedback when wrong option is passed.
571
+ in an initializer.
532
572
 
533
- `String#camelize` was returning nil without any feedback when an
534
- invalid option was passed as a parameter.
573
+ *Xavier Noria*
535
574
 
536
- Previously:
575
+ * Maintain `html_safe?` on html_safe strings when sliced.
537
576
 
538
- 'one_two'.camelize(true)
539
- # => nil
577
+ string = "<div>test</div>".html_safe
578
+ string[-1..1].html_safe? # => true
540
579
 
541
- Now:
580
+ *Elom Gomez*, *Yumin Wong*
542
581
 
543
- 'one_two'.camelize(true)
544
- # => ArgumentError: Invalid option, use either :upper or :lower.
582
+ * Add `Array#extract!`.
545
583
 
546
- *Ricardo Díaz*
584
+ The method removes and returns the elements for which the block returns a true value.
585
+ If no block is given, an Enumerator is returned instead.
547
586
 
548
- * Fix modulo operations involving durations.
587
+ numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
588
+ odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
589
+ numbers # => [0, 2, 4, 6, 8]
549
590
 
550
- Rails 5.1 introduced `ActiveSupport::Duration::Scalar` as a wrapper
551
- around numeric values as a way of ensuring a duration was the outcome of
552
- an expression. However, the implementation was missing support for modulo
553
- operations. This support has now been added and should result in a duration
554
- being returned from expressions involving modulo operations.
591
+ *bogdanvlviv*
555
592
 
556
- Prior to Rails 5.1:
593
+ * Support not to cache `nil` for `ActiveSupport::Cache#fetch`.
557
594
 
558
- 5.minutes % 2.minutes
559
- # => 60
595
+ cache.fetch('bar', skip_nil: true) { nil }
596
+ cache.exist?('bar') # => false
560
597
 
561
- Now:
598
+ *Martin Hong*
562
599
 
563
- 5.minutes % 2.minutes
564
- # => 1 minute
600
+ * Add "event object" support to the notification system.
601
+ Before this change, end users were forced to create hand made artisanal
602
+ event objects on their own, like this:
565
603
 
566
- Fixes #29603 and #29743.
604
+ ActiveSupport::Notifications.subscribe('wait') do |*args|
605
+ @event = ActiveSupport::Notifications::Event.new(*args)
606
+ end
567
607
 
568
- *Sayan Chakraborty*, *Andrew White*
608
+ ActiveSupport::Notifications.instrument('wait') do
609
+ sleep 1
610
+ end
569
611
 
570
- * Fix division where a duration is the denominator.
612
+ @event.duration # => 1000.138
571
613
 
572
- PR #29163 introduced a change in behavior when a duration was the denominator
573
- in a calculation - this was incorrect as dividing by a duration should always
574
- return a `Numeric`. The behavior of previous versions of Rails has been restored.
614
+ After this change, if the block passed to `subscribe` only takes one
615
+ parameter, the framework will yield an event object to the block. Now
616
+ end users are no longer required to make their own:
575
617
 
576
- Fixes #29592.
618
+ ActiveSupport::Notifications.subscribe('wait') do |event|
619
+ @event = event
620
+ end
577
621
 
578
- *Andrew White*
622
+ ActiveSupport::Notifications.instrument('wait') do
623
+ sleep 1
624
+ end
579
625
 
580
- * Add purpose and expiry support to `ActiveSupport::MessageVerifier` and
581
- `ActiveSupport::MessageEncryptor`.
626
+ p @event.allocations # => 7
627
+ p @event.cpu_time # => 0.256
628
+ p @event.idle_time # => 1003.2399
582
629
 
583
- For instance, to ensure a message is only usable for one intended purpose:
630
+ Now you can enjoy event objects without making them yourself. Neat!
584
631
 
585
- token = @verifier.generate("x", purpose: :shipping)
632
+ *Aaron "t.lo" Patterson*
586
633
 
587
- @verifier.verified(token, purpose: :shipping) # => "x"
588
- @verifier.verified(token) # => nil
634
+ * Add cpu_time, idle_time, and allocations to Event.
589
635
 
590
- Or make it expire after a set time:
636
+ *Eileen M. Uchitelle*, *Aaron Patterson*
591
637
 
592
- @verifier.generate("x", expires_in: 1.month)
593
- @verifier.generate("y", expires_at: Time.now.end_of_year)
638
+ * RedisCacheStore: support key expiry in increment/decrement.
594
639
 
595
- Showcased with `ActiveSupport::MessageVerifier`, but works the same for
596
- `ActiveSupport::MessageEncryptor`'s `encrypt_and_sign` and `decrypt_and_verify`.
640
+ Pass `:expires_in` to `#increment` and `#decrement` to set a Redis EXPIRE on the key.
597
641
 
598
- Pull requests: #29599, #29854
642
+ If the key is already set to expire, RedisCacheStore won't extend its expiry.
599
643
 
600
- *Assain Jaleel*
644
+ Rails.cache.increment("some_key", 1, expires_in: 2.minutes)
601
645
 
602
- * Make the order of `Hash#reverse_merge!` consistent with `HashWithIndifferentAccess`.
646
+ *Jason Lee*
603
647
 
604
- *Erol Fornoles*
648
+ * Allow `Range#===` and `Range#cover?` on Range.
605
649
 
606
- * Add `freeze_time` helper which freezes time to `Time.now` in tests.
650
+ `Range#cover?` can now accept a range argument like `Range#include?` and
651
+ `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
652
+ into a new file, with these two methods.
607
653
 
608
- *Prathamesh Sonpatki*
654
+ *Requiring active_support/core_ext/range/include_range is now deprecated.*
655
+ *Use `require "active_support/core_ext/range/compare_range"` instead.*
609
656
 
610
- * Default `ActiveSupport::MessageEncryptor` to use AES 256 GCM encryption.
657
+ *utilum*
611
658
 
612
- On for new Rails 5.2 apps. Upgrading apps can find the config as a new
613
- framework default.
659
+ * Add `index_with` to Enumerable.
614
660
 
615
- *Assain Jaleel*
661
+ Allows creating a hash from an enumerable with the value from a passed block
662
+ or a default argument.
616
663
 
617
- * Cache: `write_multi`.
664
+ %i( title body ).index_with { |attr| post.public_send(attr) }
665
+ # => { title: "hey", body: "what's up?" }
618
666
 
619
- Rails.cache.write_multi foo: 'bar', baz: 'qux'
667
+ %i( title body ).index_with(nil)
668
+ # => { title: nil, body: nil }
620
669
 
621
- Plus faster fetch_multi with stores that implement `write_multi_entries`.
622
- Keys that aren't found may be written to the cache store in one shot
623
- instead of separate writes.
670
+ Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
624
671
 
625
- The default implementation simply calls `write_entry` for each entry.
626
- Stores may override if they're capable of one-shot bulk writes, like
627
- Redis `MSET`.
672
+ *Kasper Timm Hansen*
628
673
 
629
- *Jeremy Daer*
674
+ * Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
675
+ any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
630
676
 
631
- * Add default option to module and class attribute accessors.
677
+ *Dominik Sander*
632
678
 
633
- mattr_accessor :settings, default: {}
679
+ * Redis cache store: `delete_matched` no longer blocks the Redis server.
680
+ (Switches from evaled Lua to a batched SCAN + DEL loop.)
634
681
 
635
- Works for `mattr_reader`, `mattr_writer`, `cattr_accessor`, `cattr_reader`,
636
- and `cattr_writer` as well.
682
+ *Gleb Mazovetskiy*
637
683
 
638
- *Genadi Samokovarov*
684
+ * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
685
+ size when compression is enabled (which is true by default). This patch
686
+ does not attempt to repair existing data: please manually flush the cache
687
+ to clear out the problematic entries.
639
688
 
640
- * Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
689
+ *Godfrey Chan*
641
690
 
642
- *Shota Iguchi*
691
+ * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
643
692
 
644
- * Add default option to `class_attribute`.
693
+ URI.unescape("\xe3\x83\x90") # => "バ"
694
+ URI.unescape("%E3%83%90") # => "バ"
695
+ URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
645
696
 
646
- Before:
697
+ *Ashe Connor*, *Aaron Patterson*
647
698
 
648
- class_attribute :settings
649
- self.settings = {}
699
+ * Add `before?` and `after?` methods to `Date`, `DateTime`,
700
+ `Time`, and `TimeWithZone`.
650
701
 
651
- Now:
702
+ *Nick Holden*
652
703
 
653
- class_attribute :settings, default: {}
704
+ * `ActiveSupport::Inflector#ordinal` and `ActiveSupport::Inflector#ordinalize` now support
705
+ translations through I18n.
654
706
 
655
- *DHH*
707
+ # locale/fr.rb
656
708
 
657
- * `#singularize` and `#pluralize` now respect uncountables for the specified locale.
709
+ {
710
+ fr: {
711
+ number: {
712
+ nth: {
713
+ ordinals: lambda do |_key, number:, **_options|
714
+ if number.to_i.abs == 1
715
+ 'er'
716
+ else
717
+ 'e'
718
+ end
719
+ end,
658
720
 
659
- *Eilis Hamilton*
721
+ ordinalized: lambda do |_key, number:, **_options|
722
+ "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
723
+ end
724
+ }
725
+ }
726
+ }
727
+ }
660
728
 
661
- * Add `ActiveSupport::CurrentAttributes` to provide a thread-isolated attributes singleton.
662
- Primary use case is keeping all the per-request attributes easily available to the whole system.
663
729
 
664
- *DHH*
730
+ *Christian Blais*
665
731
 
666
- * Fix implicit coercion calculations with scalars and durations.
732
+ * Add `:private` option to ActiveSupport's `Module#delegate`
733
+ in order to delegate methods as private:
667
734
 
668
- Previously, calculations where the scalar is first would be converted to a duration
669
- of seconds, but this causes issues with dates being converted to times, e.g:
735
+ class User < ActiveRecord::Base
736
+ has_one :profile
737
+ delegate :date_of_birth, to: :profile, private: true
670
738
 
671
- Time.zone = "Beijing" # => Asia/Shanghai
672
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
673
- 2 * 1.day # => 172800 seconds
674
- date + 2 * 1.day # => Mon, 22 May 2017 00:00:00 CST +08:00
739
+ def age
740
+ Date.today.year - date_of_birth.year
741
+ end
742
+ end
675
743
 
676
- Now, the `ActiveSupport::Duration::Scalar` calculation methods will try to maintain
677
- the part structure of the duration where possible, e.g:
744
+ # User.new.age # => 29
745
+ # User.new.date_of_birth
746
+ # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
678
747
 
679
- Time.zone = "Beijing" # => Asia/Shanghai
680
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
681
- 2 * 1.day # => 2 days
682
- date + 2 * 1.day # => Mon, 22 May 2017
748
+ *Tomas Valent*
683
749
 
684
- Fixes #29160, #28970.
750
+ * `String#truncate_bytes` to truncate a string to a maximum bytesize without
751
+ breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.
685
752
 
686
- *Andrew White*
753
+ *Jeremy Daer*
687
754
 
688
- * Add support for versioned cache entries. This enables the cache stores to recycle cache keys, greatly saving
689
- on storage in cases with frequent churn. Works together with the separation of `#cache_key` and `#cache_version`
690
- in Active Record and its use in Action Pack's fragment caching.
755
+ * `String#strip_heredoc` preserves frozenness.
691
756
 
692
- *DHH*
757
+ "foo".freeze.strip_heredoc.frozen? # => true
693
758
 
694
- * Pass gem name and deprecation horizon to deprecation notifications.
759
+ Fixes that frozen string literals would inadvertently become unfrozen:
695
760
 
696
- *Willem van Bergen*
761
+ # frozen_string_literal: true
697
762
 
698
- * Add support for `:offset` and `:zone` to `ActiveSupport::TimeWithZone#change`.
763
+ foo = <<-MSG.strip_heredoc
764
+ la la la
765
+ MSG
699
766
 
700
- *Andrew White*
767
+ foo.frozen? # => false !??
701
768
 
702
- * Add support for `:offset` to `Time#change`.
769
+ *Jeremy Daer*
703
770
 
704
- Fixes #28723.
771
+ * Rails 6 requires Ruby 2.5.0 or newer.
705
772
 
706
- *Andrew White*
773
+ *Jeremy Daer*, *Kasper Timm Hansen*
707
774
 
708
- * Add `fetch_values` for `HashWithIndifferentAccess`.
775
+ * Adds parallel testing to Rails.
709
776
 
710
- The method was originally added to `Hash` in Ruby 2.3.0.
777
+ Parallelize your test suite with forked processes or threads.
711
778
 
712
- *Josh Pencheon*
779
+ *Eileen M. Uchitelle*, *Aaron Patterson*
713
780
 
714
781
 
715
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activesupport/CHANGELOG.md) for previous changes.
782
+ Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activesupport/CHANGELOG.md) for previous changes.