activesupport 5.2.4.rc1 → 6.0.0.rc2

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