2022-12-21 14:38:33 +00:00
|
|
|
* Add `Rails.env.local?` shorthand for `Rails.env.development? || Rails.env.test?`.
|
|
|
|
|
|
|
|
*DHH*
|
|
|
|
|
2022-12-07 19:07:28 +00:00
|
|
|
* `ActiveSupport::Testing::TimeHelpers` now accepts named `with_usec` argument
|
|
|
|
to `freeze_time`, `travel`, and `travel_to` methods. Passing true prevents
|
|
|
|
truncating the destination time with `change(usec: 0)`.
|
|
|
|
|
|
|
|
*KevSlashNull*, and *serprex*
|
|
|
|
|
2022-07-29 16:15:43 +00:00
|
|
|
* `ActiveSupport::CurrentAttributes.resets` now accepts a method name
|
|
|
|
|
|
|
|
The block API is still the recommended approach, but now both APIs are supported:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
class Current < ActiveSupport::CurrentAttributes
|
|
|
|
resets { Time.zone = nil }
|
|
|
|
resets :clear_time_zone
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
*Alex Ghiculescu*
|
|
|
|
|
2022-07-27 04:23:43 +00:00
|
|
|
* Ensure `ActiveSupport::Testing::Isolation::Forking` closes pipes
|
|
|
|
|
|
|
|
Previously, `Forking.run_in_isolation` opened two ends of a pipe. The fork
|
|
|
|
process closed the read end, wrote to it, and then terminated (which
|
|
|
|
presumably closed the file descriptors on its end). The parent process
|
|
|
|
closed the write end, read from it, and returned, never closing the read
|
|
|
|
end.
|
|
|
|
|
|
|
|
This resulted in an accumulation of open file descriptors, which could
|
|
|
|
cause errors if the limit is reached.
|
|
|
|
|
|
|
|
*Sam Bostock*
|
|
|
|
|
Fix Time#change and #advance around the end of DST
Prior to this commit, when `Time#change` or `Time#advance` constructed a
time inside the final stretch of Daylight Saving Time (DST), the non-DST
offset would always be chosen for local times:
```ruby
# DST ended just before 2021-11-07 2:00:00 AM in US/Eastern.
ENV["TZ"] = "US/Eastern"
time = Time.local(2021, 11, 07, 00, 59, 59) + 1
# => 2021-11-07 01:00:00 -0400
time.change(day: 07)
# => 2021-11-07 01:00:00 -0500
time.advance(seconds: 0)
# => 2021-11-07 01:00:00 -0500
time = Time.local(2021, 11, 06, 01, 00, 00)
# => 2021-11-06 01:00:00 -0400
time.change(day: 07)
# => 2021-11-07 01:00:00 -0500
time.advance(days: 1)
# => 2021-11-07 01:00:00 -0500
```
And the DST offset would always be chosen for times with a `TimeZone`
object:
```ruby
Time.zone = "US/Eastern"
time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
# => 2021-11-07 01:00:00 -0500
time.change(day: 07)
# => 2021-11-07 01:00:00 -0400
time.advance(seconds: 0)
# => 2021-11-07 01:00:00 -0400
time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
# => 2021-11-08 01:00:00 -0500
time.change(day: 07)
# => 2021-11-07 01:00:00 -0400
time.advance(days: -1)
# => 2021-11-07 01:00:00 -0400
```
This commit fixes `Time#change` and `Time#advance` to choose the offset
that matches the original time's offset when possible:
```ruby
ENV["TZ"] = "US/Eastern"
time = Time.local(2021, 11, 07, 00, 59, 59) + 1
# => 2021-11-07 01:00:00 -0400
time.change(day: 07)
# => 2021-11-07 01:00:00 -0400
time.advance(seconds: 0)
# => 2021-11-07 01:00:00 -0400
time = Time.local(2021, 11, 06, 01, 00, 00)
# => 2021-11-06 01:00:00 -0400
time.change(day: 07)
# => 2021-11-07 01:00:00 -0400
time.advance(days: 1)
# => 2021-11-07 01:00:00 -0400
Time.zone = "US/Eastern"
time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
# => 2021-11-07 01:00:00 -0500
time.change(day: 07)
# => 2021-11-07 01:00:00 -0500
time.advance(seconds: 0)
# => 2021-11-07 01:00:00 -0500
time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
# => 2021-11-08 01:00:00 -0500
time.change(day: 07)
# => 2021-11-07 01:00:00 -0500
time.advance(days: -1)
# => 2021-11-07 01:00:00 -0500
```
It's worth noting that there is a somewhat dubious case when calling
`advance` with a mix of calendar and clock units (e.g. months + hours).
`advance` adds calendar units first, then adds clock units. So a
non-DST time may first be advanced to a date within DST before any clock
units are applied. For example:
```ruby
# DST began on 2021-03-14 in US/Eastern.
Time.zone = "US/Eastern"
non_dst = Time.new(2021, 03, 07, 00, 00, 00, Time.zone)
# => 2021-03-07 00:00:00 -0500
non_dst.advance(months: 8, hours: 1)
# => 2021-11-07 01:00:00 -0400
```
One could argue that the expected result is `2021-11-07 01:00:00 -0500`.
However, the difference between that and the result for `hours: 0` is
greater than 1 hour:
```ruby
adjusted_result = non_dst.advance(months: 8, hours: 1) + 3600
# => 2021-11-07 01:00:00 -0500
adjusted_result - non_dst.advance(months: 8, hours: 0)
# => 7200.0
```
Which might also be unexpected.
Furthermore, it may be difficult (or expensive) to apply such an
adjustment in a consistent way. For example, the result for `hours: 2`
does have the expected `-0500` offset, so it might seem no adjustment is
necessary, but if we didn't adjust it too, it would conflict with the
adjusted `hours: 1` result:
```ruby
non_dst.advance(months: 8, hours: 2)
# => 2021-11-07 01:00:00 -0500
```
Therefore, the approach in this commit (which produces a `-0400` offset
for `hours: 1`) seems like a reasonable compromise.
Fixes #45055.
Closes #45556.
Closes #46248.
Co-authored-by: Kevin Hall <bigtoe416@yahoo.com>
Co-authored-by: Takayoshi Nishida <takayoshi.nishida@gmail.com>
2022-10-15 19:55:40 +00:00
|
|
|
* Fix `Time#change` and `Time#advance` for times around the end of Daylight
|
|
|
|
Saving Time.
|
|
|
|
|
|
|
|
Previously, when `Time#change` or `Time#advance` constructed a time inside
|
|
|
|
the final stretch of Daylight Saving Time (DST), the non-DST offset would
|
|
|
|
always be chosen for local times:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
# DST ended just before 2021-11-07 2:00:00 AM in US/Eastern.
|
|
|
|
ENV["TZ"] = "US/Eastern"
|
|
|
|
|
|
|
|
time = Time.local(2021, 11, 07, 00, 59, 59) + 1
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.advance(seconds: 0)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
|
|
|
|
time = Time.local(2021, 11, 06, 01, 00, 00)
|
|
|
|
# => 2021-11-06 01:00:00 -0400
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.advance(days: 1)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
```
|
|
|
|
|
|
|
|
And the DST offset would always be chosen for times with a `TimeZone`
|
|
|
|
object:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
Time.zone = "US/Eastern"
|
|
|
|
|
|
|
|
time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.advance(seconds: 0)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
|
|
|
|
time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
|
|
|
|
# => 2021-11-08 01:00:00 -0500
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.advance(days: -1)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
```
|
|
|
|
|
|
|
|
Now, `Time#change` and `Time#advance` will choose the offset that matches
|
|
|
|
the original time's offset when possible:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
ENV["TZ"] = "US/Eastern"
|
|
|
|
|
|
|
|
time = Time.local(2021, 11, 07, 00, 59, 59) + 1
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.advance(seconds: 0)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
|
|
|
|
time = Time.local(2021, 11, 06, 01, 00, 00)
|
|
|
|
# => 2021-11-06 01:00:00 -0400
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
time.advance(days: 1)
|
|
|
|
# => 2021-11-07 01:00:00 -0400
|
|
|
|
|
|
|
|
Time.zone = "US/Eastern"
|
|
|
|
|
|
|
|
time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.advance(seconds: 0)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
|
|
|
|
time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
|
|
|
|
# => 2021-11-08 01:00:00 -0500
|
|
|
|
time.change(day: 07)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
time.advance(days: -1)
|
|
|
|
# => 2021-11-07 01:00:00 -0500
|
|
|
|
```
|
|
|
|
|
|
|
|
*Kevin Hall*, *Takayoshi Nishida*, and *Jonathan Hefner*
|
|
|
|
|
2022-10-22 10:30:31 +00:00
|
|
|
* Fix MemoryStore to preserve entries TTL when incrementing or decrementing
|
|
|
|
|
|
|
|
This is to be more consistent with how MemCachedStore and RedisCacheStore behaves.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-10-21 10:50:48 +00:00
|
|
|
* `Rails.error.handle` and `Rails.error.record` filter now by multiple error classes.
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
Rails.error.handle(IOError, ArgumentError) do
|
|
|
|
1 + '1' # raises TypeError
|
|
|
|
end
|
|
|
|
1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
|
|
|
|
```
|
|
|
|
|
|
|
|
*Martin Spickermann*
|
|
|
|
|
2022-09-28 08:25:45 +00:00
|
|
|
* `Class#subclasses` and `Class#descendants` now automatically filter reloaded classes.
|
|
|
|
|
|
|
|
Previously they could return old implementations of reloadable classes that have been
|
|
|
|
dereferenced but not yet garbage collected.
|
|
|
|
|
|
|
|
They now automatically filter such classes like `DescendantTracker#subclasses` and
|
|
|
|
`DescendantTracker#descendants`.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-09-26 14:19:07 +00:00
|
|
|
* `Rails.error.report` now marks errors as reported to avoid reporting them twice.
|
|
|
|
|
|
|
|
In some cases, users might want to report errors explicitly with some extra context
|
|
|
|
before letting it bubble up.
|
|
|
|
|
|
|
|
This also allows to safely catch and report errors outside of the execution context.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-09-14 10:14:06 +00:00
|
|
|
* Add `assert_error_reported` and `assert_no_error_reported`
|
|
|
|
|
|
|
|
Allows to easily asserts an error happened but was handled
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
report = assert_error_reported(IOError) do
|
|
|
|
# ...
|
|
|
|
end
|
|
|
|
assert_equal "Oops", report.error.message
|
|
|
|
assert_equal "admin", report.context[:section]
|
|
|
|
assert_equal :warning, report.severity
|
|
|
|
assert_predicate report, :handled?
|
|
|
|
```
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-09-14 20:45:53 +00:00
|
|
|
* `ActiveSupport::Deprecation` behavior callbacks can now receive the
|
|
|
|
deprecator instance as an argument. This makes it easier for such callbacks
|
|
|
|
to change their behavior based on the deprecator's state. For example,
|
|
|
|
based on the deprecator's `debug` flag.
|
|
|
|
|
|
|
|
3-arity and splat-args callbacks such as the following will now be passed
|
|
|
|
the deprecator instance as their third argument:
|
|
|
|
|
|
|
|
* `->(message, callstack, deprecator) { ... }`
|
|
|
|
* `->(*args) { ... }`
|
|
|
|
* `->(message, *other_args) { ... }`
|
|
|
|
|
|
|
|
2-arity and 4-arity callbacks such as the following will continue to behave
|
|
|
|
the same as before:
|
|
|
|
|
|
|
|
* `->(message, callstack) { ... }`
|
|
|
|
* `->(message, callstack, deprecation_horizon, gem_name) { ... }`
|
|
|
|
* `->(message, callstack, *deprecation_details) { ... }`
|
|
|
|
|
|
|
|
*Jonathan Hefner*
|
|
|
|
|
2022-09-13 20:43:41 +00:00
|
|
|
* `ActiveSupport::Deprecation#disallowed_warnings` now affects the instance on
|
|
|
|
which it is configured.
|
|
|
|
|
|
|
|
This means that individual `ActiveSupport::Deprecation` instances can be
|
|
|
|
configured with their own disallowed warnings, and the global
|
|
|
|
`ActiveSupport::Deprecation.disallowed_warnings` now only affects the global
|
|
|
|
`ActiveSupport::Deprecation.warn`.
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
|
|
|
|
deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
|
|
|
|
deprecator.disallowed_warnings = ["bar"]
|
|
|
|
|
|
|
|
ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
|
|
|
|
ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
|
|
|
|
deprecator.warn("foo") # => raise ActiveSupport::DeprecationException
|
|
|
|
deprecator.warn("bar") # => print "DEPRECATION WARNING: bar"
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
|
|
|
|
deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
|
|
|
|
deprecator.disallowed_warnings = ["bar"]
|
|
|
|
|
|
|
|
ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
|
|
|
|
ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
|
|
|
|
deprecator.warn("foo") # => print "DEPRECATION WARNING: foo"
|
|
|
|
deprecator.warn("bar") # => raise ActiveSupport::DeprecationException
|
|
|
|
```
|
|
|
|
|
|
|
|
*Jonathan Hefner*
|
|
|
|
|
2022-09-08 17:14:58 +00:00
|
|
|
* Add italic and underline support to `ActiveSupport::LogSubscriber#color`
|
|
|
|
|
|
|
|
Previously, only bold text was supported via a positional argument.
|
|
|
|
This allows for bold, italic, and underline options to be specified
|
|
|
|
for colored logs.
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
info color("Hello world!", :red, bold: true, underline: true)
|
|
|
|
```
|
|
|
|
|
|
|
|
*Gannon McGibbon*
|
|
|
|
|
2022-08-13 21:39:55 +00:00
|
|
|
* Add `String#downcase_first` method.
|
|
|
|
|
|
|
|
This method is the corollary of `String#upcase_first`.
|
|
|
|
|
|
|
|
*Mark Schneider*
|
|
|
|
|
2022-08-31 21:10:20 +00:00
|
|
|
* `thread_mattr_accessor` will call `.dup.freeze` on non-frozen default values.
|
|
|
|
|
|
|
|
This provides a basic level of protection against different threads trying
|
|
|
|
to mutate a shared default object.
|
|
|
|
|
|
|
|
*Jonathan Hefner*
|
|
|
|
|
2022-08-30 15:10:28 +00:00
|
|
|
* Add `raise_on_invalid_cache_expiration_time` config to `ActiveSupport::Cache::Store`
|
|
|
|
|
|
|
|
Specifies if an `ArgumentError` should be raised if `Rails.cache` `fetch` or
|
|
|
|
`write` are given an invalid `expires_at` or `expires_in` time.
|
|
|
|
|
|
|
|
Options are `true`, and `false`. If `false`, the exception will be reported
|
|
|
|
as `handled` and logged instead. Defaults to `true` if `config.load_defaults >= 7.1`.
|
|
|
|
|
|
|
|
*Trevor Turk*
|
|
|
|
|
2022-08-30 09:45:09 +00:00
|
|
|
* `ActiveSupport::Cache:Store#fetch` now passes an options accessor to the block.
|
|
|
|
|
|
|
|
It makes possible to override cache options:
|
|
|
|
|
|
|
|
Rails.cache.fetch("3rd-party-token") do |name, options|
|
|
|
|
token = fetch_token_from_remote
|
|
|
|
# set cache's TTL to match token's TTL
|
|
|
|
options.expires_in = token.expires_in
|
|
|
|
token
|
|
|
|
end
|
|
|
|
|
|
|
|
*Andrii Gladkyi*, *Jean Boussier*
|
|
|
|
|
2021-09-30 07:44:58 +00:00
|
|
|
* `default` option of `thread_mattr_accessor` now applies through inheritance and
|
|
|
|
also across new threads.
|
|
|
|
|
|
|
|
Previously, the `default` value provided was set only at the moment of defining
|
|
|
|
the attribute writer, which would cause the attribute to be uninitialized in
|
|
|
|
descendants and in other threads.
|
|
|
|
|
|
|
|
Fixes #43312.
|
|
|
|
|
|
|
|
*Thierry Deo*
|
|
|
|
|
2022-08-19 20:27:47 +00:00
|
|
|
* Redis cache store is now compatible with redis-rb 5.0.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-07-15 17:52:29 +00:00
|
|
|
* Add `skip_nil:` support to `ActiveSupport::Cache::Store#fetch_multi`.
|
|
|
|
|
|
|
|
*Daniel Alfaro*
|
|
|
|
|
2022-07-14 23:43:52 +00:00
|
|
|
* Add `quarter` method to date/time
|
|
|
|
|
|
|
|
*Matt Swanson*
|
|
|
|
|
2022-07-05 02:16:49 +00:00
|
|
|
* Fix `NoMethodError` on custom `ActiveSupport::Deprecation` behavior.
|
|
|
|
|
|
|
|
`ActiveSupport::Deprecation.behavior=` was supposed to accept any object
|
|
|
|
that responds to `call`, but in fact its internal implementation assumed that
|
|
|
|
this object could respond to `arity`, so it was restricted to only `Proc` objects.
|
|
|
|
|
|
|
|
This change removes this `arity` restriction of custom behaviors.
|
|
|
|
|
|
|
|
*Ryo Nakamura*
|
|
|
|
|
2022-07-08 20:36:24 +00:00
|
|
|
* Support `:url_safe` option for `MessageEncryptor`.
|
2022-06-26 23:14:34 +00:00
|
|
|
|
2022-07-08 20:36:24 +00:00
|
|
|
The `MessageEncryptor` constructor now accepts a `:url_safe` option, similar
|
2022-06-26 23:14:34 +00:00
|
|
|
to the `MessageVerifier` constructor. When enabled, this option ensures
|
|
|
|
that messages use a URL-safe encoding.
|
|
|
|
|
|
|
|
*Jonathan Hefner*
|
|
|
|
|
2022-07-08 20:36:24 +00:00
|
|
|
* Add `url_safe` option to `ActiveSupport::MessageVerifier` initializer
|
2022-06-21 11:08:20 +00:00
|
|
|
|
2022-07-08 20:36:24 +00:00
|
|
|
`ActiveSupport::MessageVerifier.new` now takes optional `url_safe` argument.
|
|
|
|
It can generate URL-safe strings by passing `url_safe: true`.
|
2022-06-21 11:08:20 +00:00
|
|
|
|
|
|
|
```ruby
|
2022-07-08 20:36:24 +00:00
|
|
|
verifier = ActiveSupport::MessageVerifier.new(url_safe: true)
|
|
|
|
message = verifier.generate(data) # => URL-safe string
|
2022-06-21 11:08:20 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
This option is `false` by default to be backwards compatible.
|
|
|
|
|
|
|
|
*Shouichi Kamiya*
|
|
|
|
|
2022-06-02 19:21:35 +00:00
|
|
|
* Enable connection pooling by default for `MemCacheStore` and `RedisCacheStore`.
|
|
|
|
|
|
|
|
If you want to disable connection pooling, set `:pool` option to `false` when configuring the cache store:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
config.cache_store = :mem_cache_store, "cache.example.com", pool: false
|
|
|
|
```
|
|
|
|
|
|
|
|
*fatkodima*
|
|
|
|
|
2022-05-25 00:18:54 +00:00
|
|
|
* Add `force:` support to `ActiveSupport::Cache::Store#fetch_multi`.
|
|
|
|
|
|
|
|
*fatkodima*
|
|
|
|
|
2022-05-16 19:47:55 +00:00
|
|
|
* Deprecated `:pool_size` and `:pool_timeout` options for configuring connection pooling in cache stores.
|
|
|
|
|
|
|
|
Use `pool: true` to enable pooling with default settings:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
config.cache_store = :redis_cache_store, pool: true
|
|
|
|
```
|
|
|
|
|
|
|
|
Or pass individual options via `:pool` option:
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
config.cache_store = :redis_cache_store, pool: { size: 10, timeout: 2 }
|
|
|
|
```
|
|
|
|
|
|
|
|
*fatkodima*
|
|
|
|
|
2022-05-11 15:44:32 +00:00
|
|
|
* Allow #increment and #decrement methods of `ActiveSupport::Cache::Store`
|
|
|
|
subclasses to set new values.
|
|
|
|
|
|
|
|
Previously incrementing or decrementing an unset key would fail and return
|
|
|
|
nil. A default will now be assumed and the key will be created.
|
|
|
|
|
|
|
|
*Andrej Blagojević*, *Eugene Kenny*
|
|
|
|
|
2022-05-15 10:45:22 +00:00
|
|
|
* Add `skip_nil:` support to `RedisCacheStore`
|
|
|
|
|
|
|
|
*Joey Paris*
|
|
|
|
|
2022-05-11 18:20:01 +00:00
|
|
|
* `ActiveSupport::Cache::MemoryStore#write(name, val, unless_exist:true)` now
|
|
|
|
correctly writes expired keys.
|
|
|
|
|
|
|
|
*Alan Savage*
|
|
|
|
|
2022-05-02 10:02:39 +00:00
|
|
|
* `ActiveSupport::ErrorReporter` now accepts and forward a `source:` parameter.
|
|
|
|
|
|
|
|
This allow libraries to signal the origin of the errors, and reporters
|
|
|
|
to easily ignore some sources.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-01-05 15:37:54 +00:00
|
|
|
* Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
|
|
|
|
|
|
|
|
Add the method `ERB::Util.xml_name_escape` to escape dangerous characters
|
|
|
|
in names of tags and names of attributes, following the specification of XML.
|
|
|
|
|
|
|
|
*Álvaro Martín Fraguas*
|
|
|
|
|
2022-04-22 23:45:59 +00:00
|
|
|
* Respect `ActiveSupport::Logger.new`'s `:formatter` keyword argument
|
|
|
|
|
|
|
|
The stdlib `Logger::new` allows passing a `:formatter` keyword argument to
|
|
|
|
set the logger's formatter. Previously `ActiveSupport::Logger.new` ignored
|
|
|
|
that argument by always setting the formatter to an instance of
|
|
|
|
`ActiveSupport::Logger::SimpleFormatter`.
|
|
|
|
|
|
|
|
*Steven Harman*
|
|
|
|
|
2022-03-20 10:07:59 +00:00
|
|
|
* Deprecate preserving the pre-Ruby 2.4 behavior of `to_time`
|
|
|
|
|
|
|
|
With Ruby 2.4+ the default for +to_time+ changed from converting to the
|
|
|
|
local system time to preserving the offset of the receiver. At the time Rails
|
|
|
|
supported older versions of Ruby so a compatibility layer was added to assist
|
2022-04-22 23:45:59 +00:00
|
|
|
in the migration process. From Rails 5.0 new applications have defaulted to
|
2022-03-20 10:07:59 +00:00
|
|
|
the Ruby 2.4+ behavior and since Rails 7.0 now only supports Ruby 2.7+
|
|
|
|
this compatibility layer can be safely removed.
|
2022-04-22 23:45:59 +00:00
|
|
|
|
2022-03-20 10:07:59 +00:00
|
|
|
To minimize any noise generated the deprecation warning only appears when the
|
|
|
|
setting is configured to `false` as that is the only scenario where the
|
|
|
|
removal of the compatibility layer has any effect.
|
2022-04-22 23:45:59 +00:00
|
|
|
|
2022-03-20 10:07:59 +00:00
|
|
|
*Andrew White*
|
|
|
|
|
2022-02-19 08:52:02 +00:00
|
|
|
* `Pathname.blank?` only returns true for `Pathname.new("")`
|
|
|
|
|
|
|
|
Previously it would end up calling `Pathname#empty?` which returned true
|
|
|
|
if the path existed and was an empty directory or file.
|
|
|
|
|
|
|
|
That behavior was unlikely to be expected.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
|
|
|
|
2022-01-17 18:49:31 +00:00
|
|
|
* Deprecate `Notification::Event`'s `#children` and `#parent_of?`
|
|
|
|
|
2022-07-11 05:43:32 +00:00
|
|
|
*John Hawthorn*
|
|
|
|
|
2021-07-20 15:24:51 +00:00
|
|
|
* Change default serialization format of `MessageEncryptor` from `Marshal` to `JSON` for Rails 7.1.
|
|
|
|
|
|
|
|
Existing apps are provided with an upgrade path to migrate to `JSON` as described in `guides/source/upgrading_ruby_on_rails.md`
|
|
|
|
|
|
|
|
*Zack Deveau* and *Martin Gingras*
|
|
|
|
|
2022-02-01 11:20:06 +00:00
|
|
|
* Add `ActiveSupport::TestCase#stub_const` to stub a constant for the duration of a yield.
|
|
|
|
|
|
|
|
*DHH*
|
|
|
|
|
2022-01-04 13:42:02 +00:00
|
|
|
* Fix `ActiveSupport::EncryptedConfiguration` to be compatible with Psych 4
|
|
|
|
|
|
|
|
*Stephen Sugden*
|
|
|
|
|
2022-01-12 00:47:01 +00:00
|
|
|
* Improve `File.atomic_write` error handling
|
|
|
|
|
2022-07-11 05:43:32 +00:00
|
|
|
*Daniel Pepper*
|
|
|
|
|
2021-12-21 08:54:14 +00:00
|
|
|
* Fix `Class#descendants` and `DescendantsTracker#descendants` compatibility with Ruby 3.1.
|
2021-12-03 19:41:41 +00:00
|
|
|
|
2021-12-21 08:54:14 +00:00
|
|
|
[The native `Class#descendants` was reverted prior to Ruby 3.1 release](https://bugs.ruby-lang.org/issues/14394#note-33),
|
|
|
|
but `Class#subclasses` was kept, breaking the feature detection.
|
|
|
|
|
|
|
|
*Jean Boussier*
|
2021-12-03 19:41:41 +00:00
|
|
|
|
2021-12-07 15:52:30 +00:00
|
|
|
Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activesupport/CHANGELOG.md) for previous changes.
|