* Fix modulo operations involving durations
Rails 5.1 introduce an `ActiveSupport::Duration::Scalar` class as a wrapper
around a numeric value as a way of ensuring a duration was the outcome of
an expression. However the implementation was missing support for modulo
operations. This support has now been added and should result in a duration
being returned from expressions involving modulo operations.
Prior to Rails 5.1:
5.minutes % 2.minutes
=> 60
Now:
5.minutes % 2.minutes
=> 1 minute
Fixes #29603 and #29743.
*Sayan Chakraborty*, *Andrew White*
* Fix division where a duration is the denominator
PR #29163 introduced a change in behavior when a duration was the denominator
in a calculation - this was incorrect as dividing by a duration should always
return a `Numeric`. The behavior of previous versions of Rails has been restored.
Fixes #29592.
*Andrew White*
* Add purpose and expiry support to `ActiveSupport::MessageVerifier` &
`ActiveSupport::MessageEncryptor`.
For instance, to ensure a message is only usable for one intended purpose:
token = @verifier.generate("x", purpose: :shipping)
@verifier.verified(token, purpose: :shipping) # => "x"
@verifier.verified(token) # => nil
Or make it expire after a set time:
@verifier.generate("x", expires_in: 1.month)
@verifier.generate("y", expires_at: Time.now.end_of_year)
Showcased with `ActiveSupport::MessageVerifier`, but works the same for
`ActiveSupport::MessageEncryptor`'s `encrypt_and_sign` and `decrypt_and_verify`.
Pull requests: #29599, #29854
*Assain Jaleel*
* Make the order of `Hash#reverse_merge!` consistent with `HashWithIndifferentAccess`.
*Erol Fornoles*
* Add `freeze_time` helper which freezes time to `Time.now` in tests.
*Prathamesh Sonpatki*
* Default `ActiveSupport::MessageEncryptor` to use AES 256 GCM encryption.
On for new Rails 5.2 apps. Upgrading apps can find the config as a new
framework default.
*Assain Jaleel*
* Cache: `write_multi`
Rails.cache.write_multi foo: 'bar', baz: 'qux'
Plus faster fetch_multi with stores that implement `write_multi_entries`.
Keys that aren't found may be written to the cache store in one shot
instead of separate writes.
The default implementation simply calls `write_entry` for each entry.
Stores may override if they're capable of one-shot bulk writes, like
Redis `MSET`.
*Jeremy Daer*
* Add default option to module and class attribute accessors.
mattr_accessor :settings, default: {}
Works for `mattr_reader`, `mattr_writer`, `cattr_accessor`, `cattr_reader`,
and `cattr_writer` as well.
*Genadi Samokovarov*
* Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
*Shota Iguchi*
* Add default option to `class_attribute`.
Before:
class_attribute :settings
self.settings = {}
Now:
class_attribute :settings, default: {}
*DHH*
* `#singularize` and `#pluralize` now respect uncountables for the specified locale.
*Eilis Hamilton*
* Add `ActiveSupport::CurrentAttributes` to provide a thread-isolated attributes singleton.
Primary use case is keeping all the per-request attributes easily available to the whole system.
*DHH*
* Fix implicit coercion calculations with scalars and durations
Previously calculations where the scalar is first would be converted to a duration
of seconds but this causes issues with dates being converted to times, e.g:
Time.zone = "Beijing" # => Asia/Shanghai
date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
2 * 1.day # => 172800 seconds
date + 2 * 1.day # => Mon, 22 May 2017 00:00:00 CST +08:00
Now the `ActiveSupport::Duration::Scalar` calculation methods will try to maintain
the part structure of the duration where possible, e.g:
Time.zone = "Beijing" # => Asia/Shanghai
date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
2 * 1.day # => 2 days
date + 2 * 1.day # => Mon, 22 May 2017
Fixes #29160, #28970.
*Andrew White*
* Add support for versioned cache entries. This enables the cache stores to recycle cache keys, greatly saving
on storage in cases with frequent churn. Works together with the separation of `#cache_key` and `#cache_version`
in Active Record and its use in Action Pack's fragment caching.
*DHH*
* Pass gem name and deprecation horizon to deprecation notifications.
*Willem van Bergen*
* Add support for `:offset` and `:zone` to `ActiveSupport::TimeWithZone#change`
*Andrew White*
* Add support for `:offset` to `Time#change`
Fixes #28723.
*Andrew White*
* Add `fetch_values` for `HashWithIndifferentAccess`
The method was originally added to `Hash` in Ruby 2.3.0.
*Josh Pencheon*
Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activesupport/CHANGELOG.md) for previous changes.