* Allow Range#=== and Range#cover? on Range `Range#cover?` can now accept a range argument like `Range#include?` and `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved into a new file, with these two methods. *Requiring active_support/core_ext/range/include_range is now deprecated.* *Use `require "active_support/core_ext/range/compare_range"` instead.* *utilum* * Add `index_with` to Enumerable. Allows creating a hash from an enumerable with the value from a passed block or a default argument. %i( title body ).index_with { |attr| post.public_send(attr) } # => { title: "hey", body: "what's up?" } %i( title body ).index_with(nil) # => { title: nil, body: nil } Closely linked with `index_by`, which creates a hash where the keys are extracted from a block. *Kasper Timm Hansen* * Fix bug where `ActiveSupport::Timezone.all` would fail when tzinfo data for any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing. *Dominik Sander* * Redis cache store: `delete_matched` no longer blocks the Redis server. (Switches from evaled Lua to a batched SCAN + DEL loop.) *Gleb Mazovetskiy* * Fix bug where `ActiveSupport::Cache` will massively inflate the storage size when compression is enabled (which is true by default). This patch does not attempt to repair existing data: please manually flush the cache to clear out the problematic entries. *Godfrey Chan* * Fix bug where `URI.unscape` would fail with mixed Unicode/escaped character input: URI.unescape("\xe3\x83\x90") # => "バ" URI.unescape("%E3%83%90") # => "バ" URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError *Ashe Connor*, *Aaron Patterson* * Add `before?` and `after?` methods to `Date`, `DateTime`, `Time`, and `TimeWithZone`. *Nick Holden* * `ActiveSupport::Inflector#ordinal` and `ActiveSupport::Inflector#ordinalize` now support translations through I18n. # locale/fr.rb { fr: { number: { nth: { ordinals: lambda do |_key, number:, **_options| if number.to_i.abs == 1 'er' else 'e' end end, ordinalized: lambda do |_key, number:, **_options| "#{number}#{ActiveSupport::Inflector.ordinal(number)}" end } } } } *Christian Blais* * Add `:private` option to ActiveSupport's `Module#delegate` in order to delegate methods as private: class User < ActiveRecord::Base has_one :profile delegate :date_of_birth, to: :profile, private: true def age Date.today.year - date_of_birth.year end end # User.new.age # => 29 # User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for # *Tomas Valent* * `String#truncate_bytes` to truncate a string to a maximum bytesize without breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦. *Jeremy Daer* * `String#strip_heredoc` preserves frozenness. "foo".freeze.strip_heredoc.frozen? # => true Fixes that frozen string literals would inadvertently become unfrozen: # frozen_string_literal: true foo = <<-MSG.strip_heredoc la la la MSG foo.frozen? # => false !?? *Jeremy Daer* * Rails 6 requires Ruby 2.4.1 or newer. *Jeremy Daer* * Adds parallel testing to Rails. Parallelize your test suite with forked processes or threads. *Eileen M. Uchitelle*, *Aaron Patterson* Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activesupport/CHANGELOG.md) for previous changes.