Rails 6.0.2.rc1 (November 27, 2019)
Eager load translations during initialization.
Diego Plentz
Use per-thread CPU time clock on
ActiveSupport::Notifications
.George Claghorn
Rails 6.0.1 (November 5, 2019)
ActiveSupport::SafeBuffer
supportsEnumerator
methods.Shugo Maeda
The Redis cache store fails gracefully when the server returns a “max number
of clients reached” error.Brandon Medenwald
Fixed that mutating a value returned by a memory cache store would
unexpectedly change the cached value.Jonathan Hyman
The default inflectors in
zeitwerk
mode support overrides:# config/initializers/zeitwerk.rb Rails.autoloaders.each do |autoloader| autoloader.inflector.inflect( "html_parser" => "HTMLParser", "ssl_error" => "SSLError" ) end
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.Please, check the autoloading guide for
zeitwerk
mode if you prefer not to depend onString#camelize
at all.Xavier Noria
Improve
Range#===
,Range#include?
, andRange#cover?
to work with beginless (startless)
and endless range targets.Allen Hsu, Andrew Hodgkinson
Don’t use
Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)
on Solaris.Iain Beeston
Rails 6.0.0 (August 16, 2019)
Let
require_dependency
inzeitwerk
mode look the autoload paths up for
better backwards compatibility.Xavier Noria
Let
require_dependency
inzeitwerk
mode support arguments that respond
toto_path
for better backwards compatibility.Xavier Noria
Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
Use
Fiber.current.__id__
inActiveSupport::Logger#local_level=
in order
to make log level local to Ruby Fibers in addition to Threads.Example:
logger = ActiveSupport::Logger.new(STDOUT)
logger.level = 1
p “Main is debug? #{logger.debug?}”Fiber.new {
logger.local_level = 0
p “Thread is debug? #{logger.debug?}”
}.resumep “Main is debug? #{logger.debug?}”
Before:
Main is debug? false
Thread is debug? true
Main is debug? trueAfter:
Main is debug? false
Thread is debug? true
Main is debug? falseAlexander Varnin
Do not delegate missing
marshal_dump
and_dump
methods via the
delegate_missing_to
extension. This avoids unintentionally adding instance
variables when callingMarshal.dump(object)
, should the delegation target of
object
be a method which would otherwise add them. Fixes #36522.Aaron Lipman
Rails 6.0.0.rc2 (July 22, 2019)
truncate
would return the original string if it was too short to be truncated
and a frozen string if it were long enough to be truncated. Now truncate will
consistently return an unfrozen string regardless. This behavior is consistent
withgsub
andstrip
.Before:
‘foobar’.truncate(5).frozen?
# => true
‘foobar’.truncate(6).frozen?
# => falseAfter:
‘foobar’.truncate(5).frozen?
# => false
‘foobar’.truncate(6).frozen?
# => falseJordan Thomas
Rails 6.0.0.rc1 (April 24, 2019)
Introduce
ActiveSupport::ActionableError
.Actionable errors let’s you dispatch actions from Rails’ error pages. This
can help you save time if you have a clear action for the resolution of
common development errors.The de-facto example are pending migrations. Every time pending migrations
are found, a middleware raises an error. With actionable errors, you can
run the migrations right from the error page. Other examples include Rails
plugins that need to run a rake task to setup themselves. They can now
raise actionable errors to run the setup straight from the error pages.Here is how to define an actionable error:
class PendingMigrationError < MigrationError #:nodoc: include ActiveSupport::ActionableError action "Run pending migrations" do ActiveRecord::Tasks::DatabaseTasks.migrate end end
To make an error actionable, include the
ActiveSupport::ActionableError
module and invoke theaction
class macro to define the action. An action
needs a name and a procedure to execute. The name is shown as the name of a
button on the error pages. Once clicked, it will invoke the given
procedure.Vipul A M, Yao Jie, Genadi Samokovarov
Preserve
html_safe?
status onActiveSupport::SafeBuffer#*
.Before:
(“
”.html_safe * 2).html_safe? #=> nilAfter:
(“
”.html_safe * 2).html_safe? #=> trueRyo Nakamura
Calling test methods with
with_info_handler
method to allow minitest-hooks
plugin to work.Mauri Mustonen
The Zeitwerk compatibility interface for
ActiveSupport::Dependencies
no
longer implementsautoloaded_constants
orautoloaded?
(undocumented,
anyway). Experience shows introspection does not have many use cases, and
troubleshooting is done by logging. With this design trade-off we are able
to use even less memory in all environments.Xavier Noria
Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
and hence uses less memory whenconfig.cache_classes
istrue
, a standard
setup in production.Xavier Noria
In
:zeitwerk
mode, eager load directories in engines and applications only
if present in their respectiveconfig.eager_load_paths
.A common use case for this is adding
lib
toconfig.autoload_paths
, but
not toconfig.eager_load_paths
. In that configuration, for example, files
in thelib
directory should not be eager loaded.Xavier Noria
Fix bug in Range comparisons when comparing to an excluded-end Range
Before:
(1..10).cover?(1…11) # => false
After:
(1..10).cover?(1…11) # => true
With the same change for
Range#include?
andRange#===
.Owen Stephens
Use weak references in descendants tracker to allow anonymous subclasses to
be garbage collected.Edgars Beigarts
Update
ActiveSupport::Notifications::Instrumenter#instrument
to make
passing a block optional. This will let users use
ActiveSupport::Notifications
messaging features outside of
instrumentation.Ali Ibrahim
Fix
Time#advance
to work with dates before 1001-03-07Before:
Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
After
Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC
Note that this doesn’t affect
DateTime#advance
as that doesn’t use a proleptic calendar.Andrew White
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.Xavier Noria
Add support for supplying
locale
totransliterate
andparameterize
.I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { “ü” => “ue” } } })
ActiveSupport::Inflector.transliterate(“ü”, locale: :de) # => “ue”
“Fünf autos”.parameterize(locale: :de) # => “fuenf-autos”
ActiveSupport::Inflector.parameterize(“Fünf autos”, locale: :de) # => “fuenf-autos”Kaan Ozkan, Sharang Dashputre
Allow
Array#excluding
andEnumerable#excluding
to deal with a passed array gracefully.[ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
DHH
Renamed
Array#without
andEnumerable#without
toArray#excluding
andEnumerable#excluding
, to create parity with
Array#including
andEnumerable#including
. Retained the old names as aliases.DHH
Added
Array#including
andEnumerable#including
to conveniently enlarge a collection with more members using a method rather than an operator:[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
post.authors.including(Current.person) # => All the authors plus the current person!DHH
Rails 6.0.0.beta3 (March 11, 2019)
- No changes.
Rails 6.0.0.beta2 (February 25, 2019)
New autoloading based on Zeitwerk.
Xavier Noria
Revise
ActiveSupport::Notifications.unsubscribe
to correctly handle Regex or other multiple-pattern subscribers.Zach Kemp
Add
before_reset
callback toCurrentAttributes
and defineafter_reset
as an alias ofresets
for symmetry.Rosa Gutierrez
Remove the
Kernel#`
override that suppresses ENOENT and accidentally returns nil on Unix systems.Akinori Musha
Add
ActiveSupport::HashWithIndifferentAccess#assoc
.assoc
can now be called with either a string or a symbol.Stefan Schüßler
Add
Hash#deep_transform_values
, andHash#deep_transform_values!
.Guillermo Iguaran
Rails 6.0.0.beta1 (January 18, 2019)
Remove deprecated
Module#reachable?
method.Rafael Mendonça França
Remove deprecated
#acronym_regex
method fromInflections
.Rafael Mendonça França
Fix
String#safe_constantize
throwing aLoadError
for incorrectly cased constant references.Keenan Brock
Preserve key order passed to
ActiveSupport::CacheStore#fetch_multi
.fetch_multi(*names)
now returns its results in the same order as the*names
requested, rather than returning cache hits followed by cache misses.Gannon McGibbon
If the same block is
included
multiple times for a Concern, an exception is no longer raised.Mark J. Titorenko, Vlad Bokov
Fix bug where
#to_options
forActiveSupport::HashWithIndifferentAccess
would not act as alias for#symbolize_keys
.Nick Weiland
Improve the logic that detects non-autoloaded constants.
Jan Habermann, Xavier Noria
Deprecate
ActiveSupport::Multibyte::Unicode#pack_graphemes(array)
andActiveSupport::Multibyte::Unicode#unpack_graphemes(string)
in favor ofarray.flatten.pack("U*")
andstring.scan(/\X/).map(&:codepoints)
, respectively.Francesco Rodríguez
Deprecate
ActiveSupport::Multibyte::Chars.consumes?
in favor ofString#is_utf8?
.Francesco Rodríguez
Fix duration being rounded to a full second.
time = DateTime.parse("2018-1-1") time += 0.51.seconds
Will now correctly add 0.51 second and not 1 full second.
Edouard Chin
Deprecate
ActiveSupport::Multibyte::Unicode#normalize
andActiveSupport::Multibyte::Chars#normalize
in favor ofString#unicode_normalize
Francesco Rodríguez
Deprecate
ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase
in favor of
String#downcase/upcase/swapcase
.Francesco Rodríguez
Add
ActiveSupport::ParameterFilter
.Yoshiyuki Kinjo
Rename
Module#parent
,Module#parents
, andModule#parent_name
to
module_parent
,module_parents
, andmodule_parent_name
.Gannon McGibbon
Deprecate the use of
LoggerSilence
in favor ofActiveSupport::LoggerSilence
Edouard Chin
Deprecate using negative limits in
String#first
andString#last
.Gannon McGibbon, Eric Turner
Fix bug where
#without
forActiveSupport::HashWithIndifferentAccess
would fail
with symbol argumentsAbraham Chan
Treat
#delete_prefix
,#delete_suffix
and#unicode_normalize
results as non-html_safe
.
Ensure safety of arguments for#insert
,#[]=
and#replace
calls onhtml_safe
Strings.Janosch Müller
Changed
ActiveSupport::TaggedLogging.new
to return a new logger instance instead
of mutating the one received as parameter.Thierry Joyal
Define
unfreeze_time
as an alias oftravel_back
inActiveSupport::Testing::TimeHelpers
.The alias is provided for symmetry with
freeze_time
.Ryan Davidson
Add support for tracing constant autoloads. Just throw
ActiveSupport::Dependencies.logger = Rails.logger
ActiveSupport::Dependencies.verbose = truein an initializer.
Xavier Noria
Maintain
html_safe?
on html_safe strings when sliced.string = “
test”.html_safe
string[-1..1].html_safe? # => trueElom Gomez, Yumin Wong
Add
Array#extract!
.The method removes and returns the elements for which the block returns a true value.
If no block is given, an Enumerator is returned instead.numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]bogdanvlviv
Support not to cache
nil
forActiveSupport::Cache#fetch
.cache.fetch(‘bar’, skip_nil: true) { nil }
cache.exist?(‘bar’) # => falseMartin Hong
Add “event object” support to the notification system.
Before this change, end users were forced to create hand made artisanal
event objects on their own, like this:ActiveSupport::Notifications.subscribe(‘wait’) do |*args|
@event = ActiveSupport::Notifications::Event.new(*args)
endActiveSupport::Notifications.instrument(‘wait’) do
sleep 1
end@event.duration # => 1000.138
After this change, if the block passed to
subscribe
only takes one
parameter, the framework will yield an event object to the block. Now
end users are no longer required to make their own:ActiveSupport::Notifications.subscribe(‘wait’) do |event|
@event = event
endActiveSupport::Notifications.instrument(‘wait’) do
sleep 1
endp @event.allocations # => 7
p @event.cpu_time # => 0.256
p @event.idle_time # => 1003.2399Now you can enjoy event objects without making them yourself. Neat!
Aaron “t.lo” Patterson
Add cpu_time, idle_time, and allocations to Event.
Eileen M. Uchitelle, Aaron Patterson
RedisCacheStore: support key expiry in increment/decrement.
Pass
:expires_in
to#increment
and#decrement
to set a Redis EXPIRE on the key.If the key is already set to expire, RedisCacheStore won’t extend its expiry.
Rails.cache.increment(“some_key”, 1, expires_in: 2.minutes)
Jason Lee
Allow
Range#===
andRange#cover?
on Range.Range#cover?
can now accept a range argument likeRange#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.
Userequire "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 inActiveSupport::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.unescape
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::CompatibilityErrorAshe Connor, Aaron Patterson
Add
before?
andafter?
methods toDate
,DateTime
,
Time
, andTimeWithZone
.Nick Holden
ActiveSupport::Inflector#ordinal
andActiveSupport::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’sModule#delegate
in order to delegate methods as private:class User < ActiveRecord::Base
has_one :profile
delegate :date_of_birth, to: :profile, private: truedef 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
MSGfoo.frozen? # => false !??
Jeremy Daer
Rails 6 requires Ruby 2.5.0 or newer.
Jeremy Daer, Kasper Timm Hansen
Adds parallel testing to Rails.
Parallelize your test suite with forked processes or threads.
Eileen M. Uchitelle, Aaron Patterson
Please check 5-2-stable for previous changes.