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