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