activesupport 5.2.2.1 → 6.0.2

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