Active Support
-
Fix the debug error page rendering for
SyntaxErrors with multi-line messages.Marco Roth
-
Make
ActiveSupport::JSON.decodecompatible with the upcomingjson3.0 gem.Earlopain
-
Fix
number_to_human_sizecrashing for sizes above a terabyte by supporting
petabyte, exabyte, and zettabyte storage units.Kenta Ishizaki
-
Fix
Range#soleraisingNoMethodErrorwhen the enumerable core extension
isn't already loaded.Kenta Ishizaki
-
Fix
ActiveSupport::Cache::FileStoreraisingNameErrorforFileUtils
whenfileutilsisn't already loaded.Kenta Ishizaki
-
Fix
Enumerable#in_order_ofwithfilter: truedroppingnilelements
explicitly named in the series.Kenta Ishizaki
-
Keep
HashWithIndifferentAccess#filterreturning aHashWithIndifferentAccess
instead of a plainHash.Kenta Ishizaki
-
Fix
number_to_humanandnumber_to_human_sizecrashing when:precisionisnil.Kenta Ishizaki
-
Fix
ActiveSupport::InheritableOptions#to_hto recursively flatten nested
InheritableOptionsparents.Andrew Novoselac
-
Fix
ActiveSupport::StructuredEventSubscriber.debug_onlyleaking debug-only
methods across subscriber subclasses.Kenta Ishizaki
-
Fix
ActiveSupport::Inflector#transliteratemutating the caller's string.Kenta Ishizaki
-
Fix
Hash.from_xmlraisingDate::Errorontype="date"values surrounded
by whitespace.Kenta Ishizaki
-
Fix
Time#advanceandDateTime#advancemutating the options hash passed
by the caller.Kenta Ishizaki
-
Fix
ActiveSupport::Cache::MemoryStore#cleanupraisingNoMethodErrorwhen
used with a non-DupCoderserializer.Kenta Ishizaki
-
Fix
String#truncatewith:separatormisbehaving when the:omissionis
longer than the target length.Kenta Ishizaki
-
Fix
ActiveSupport::Cache::Store#delete_multimutating the names array passed
by the caller.Kenta Ishizaki
-
Fix
number_to_currencycrashing on a negative number when:precisionisnil.Kenta Ishizaki
-
Fix
TimeZone#strptimewith%sdropping the sub-second fraction of the timestamp.Kenta Ishizaki
-
Fix
HashWithIndifferentAccess.newdropping a falsy (falseor0) default
value from the source hash.Kenta Ishizaki
-
Fix
Range#include?andRange#===raising on exclusive non-integer sub-ranges.Kenta Ishizaki
-
Fix
number_to_delimitedcorrupting numbers that begin with a+or-sign.Kenta Ishizaki
-
Fix
ActiveSupport::InheritableOptions#==raisingNoMethodErrorwhen compared
with a non-Hash object.Kenta Ishizaki
-
Fix
Enumerable#in_order_ofwithfilter: falsedropping elements whose keyed
value isnil.Hammad Khan
-
Stop the DRb service when shutting down parallel test workers, preventing it
from lingering after the test run.Shuta Mugikura
-
Preserve the encoding of
ActiveSupport::SafeBuffervalues round-tripped through
ActiveSupport::MessagePack.Rafael Mendonça França
-
Fix
number_to_phonewithout an area code stripping a leading delimiter when the
number itself coincidentally starts with the delimiter string.Tahsin Hasan
-
Update
ActiveSupport::TimeZonemappings to use the current IANA identifiers
Europe/Kyiv(wasEurope/Kiev) andAsia/Yangon(wasAsia/Rangoon).tsymbalenkovlad
-
Use the faster string-based delimiter logic by default in
number_to_delimited,
instead of the regular expression fallback.Shinichi Maeshima
-
Preserve the requested key order in
ActiveSupport::Cache::Store#fetch_multi
when a local cache is active.Previously, if some keys were served from the local cache and others from the
underlying store,fetch_multireturned the local cache hits first instead of
following the order of the requested keys.Mueez Afzal
-
Fix
String#parameterizeraisingTypeErrorwhenseparatorisnil.parameterizealready treats anilseparator the same as an empty one when
squeezing and trimming separators, but raisedTypeErrorbefore reaching that
point. Anilseparator now behaves like"", removing the unwanted characters."Donald E. Knuth".parameterize(separator: nil) # => "donaldeknuth"
Hammad Khan
-
Add
RedisClient::ErrortoActiveSupport::Cache::RedisCacheStore's failsafe rescue list.The redis-rb gem normally translates
RedisClient::*errors intoRedis::*errors but in
some rare cases, such as when using sentinels,RedisClient::*errors may slip through.David Arrunategui
-
Fix
ActiveSupport::Duration#in_minutes,#in_hours,#in_days,
#in_weeks,#in_months, and#in_yearstruncating sub-second precision.These methods divided the duration's integer second count (
in_seconds,
aliased toto_i) instead of its exact value, so any fractional second was
silently dropped before the conversion.# Before 90.5.seconds.in_minutes # => 1.5 # After 90.5.seconds.in_minutes # => 1.5083333333333333
Kenta Ishizaki
-
Fix JSON encoding of non-String Hash keys.
The old encoder would simply call
to_son them, the newer encoder
would incorrectly callas_jsoninstead.In the case of
Time,DateTimeandTimeWithZonethis would result
in different serialization of time keys:"2009-01-01T12:30:00.000Z"(arguably better)
instead of"2009-01-01 12:30:00 UTC"(how it used to be).Kenta Ishizaki
-
Fix
number_to_phonedropping only the first character of a
multi-character:delimiterwhen no area code is present.The leading delimiter produced by an empty first capture group was
stripped withslice!(0, 1), which assumed a single-character
delimiter. Multi-character (and multibyte) delimiters now work:number_to_phone(5551234, delimiter: " - ") # => "555 - 1234" # was "- 555 - 1234"Kenta Ishizaki
-
Fix
titleizeinflector to consider Unicode characters"ćasim đipa".titleize # => "Ćasim Đipa"
Eldin Guzin
Active Model
-
Fix
ActiveModel::Errors#importmutating the override options hash passed to it.Kenta Ishizaki
-
Fix
normalizesnot detecting in-place changes for attributes whose database
cast type differs from the attribute type (e.g. JSON columns), causing
normalization to be skipped on validation.Chedli Bourguiba
-
Fix
alias_attributeaccumulating duplicate entries inaliases_by_attribute_name
when called multiple times with the same arguments.Nicholas Jakobsen
-
Fix
normalizesre-applying normalizations on every validation of an
unpersisted record, and speed up validation of normalized attributes.The in-place mutation check re-ran the normalizer on every
valid?of an
unpersisted record: wasteful for idempotent normalizers and compounded the
result for non-idempotent ones. Normalizations are now re-applied only on a
genuine in-place mutation.Yaroslav Markin
-
Limit the size of strings
ActiveModel::Type::Integerwill coerce withto_i.Calling
to_ion very long strings can take a long time and could be used as
a DoS vector. Integer casting now only considers the first_limit * 4bytes
of a string (16 bytes for a default 4-byte integer, 32 bytes for an 8-byte
bigint), which is enough to hold the maximum representable value plus a sign
or a short slug suffix.Aaron Patterson, Jean Boussier
Active Record
-
Avoid deadlocks when concurrent
find_or_create_bycalls read back the same
record within MySQL transactions.Use a shared lock for the read after a duplicate insert, preserving visibility
under REPEATABLE READ without upgrading competing shared locks to exclusive locks.
This also applies tocreate_or_find_byand the bang variants of both methods.Fixes #54281.
Kirsten Westeinde
-
Filter the database password out of failed
db:task command error messages.Ngan Pham
-
Fix
ActiveRecord::TypeCaster::Connectionsometimes leaking a checked-out
connection.Hartley McGuire
-
Fix PostgreSQL exclusion constraints with multiline expressions being parsed
incorrectly during schema introspection.Jake McAllister
-
Fix async
ActiveRecord::StatementCache#executeraising an error for
out-of-range bind values instead of returning an empty result.viralpraxis
-
Fix
whereclauses with column-tuple syntax not resolving references to
other tables.Chris Gunther
-
Fix
distinct: truebeing ignored byaverage.Kenta Ishizaki
-
Fix
belongs_tochange tracking for composite foreign keys.Only the first foreign key column was checked for changes; now all foreign
key columns are checked.Anas Khan
-
Make
add_column(if_not_exists: true)reversible.Kenta Ishizaki
-
Quote the index name in MySQL
enable_indexanddisable_index.Unquoted index names containing special characters could cause SQL syntax
errors.Kenta Ishizaki
-
Make
remove_foreign_key(if_exists: true)reversible.Kenta Ishizaki
-
Fix
distinct: truebeing ignored by groupedsum.Kenta Ishizaki
-
Return an
ActiveRecord::Promisefromasync_idson a contradictory
relation, instead of a plainActiveRecord::Result.Kenta Ishizaki
-
Fix reversibility check for
drop_virtual_table.The wrong argument was extracted, so the check for whether options were
given could pass or fail incorrectly.Kenta Ishizaki
-
Fix
remove_check_constraint(if_exists: true)incorrectly raising when
removing by expression.The
if_existscheck did not pass the expression to
check_constraint_exists?, so it could not find the constraint.Kenta Ishizaki
-
Clear PostgreSQL notices as they are handled, preventing warnings from
leaking to subsequent queries.Matthew Draper
-
Fix
WeakThreadKeyMapraising "can't add a new key into hash during
iteration" when connections are checked in from multiple threads.Matthew Draper
-
Continue pool disconnect after a connection's cleanup or disconnect raises.
Previously, a failure on one connection aborted the teardown, stranding
remaining connections and their resources.Matthew Draper
-
Fix race condition between
preconnectand the connection pool reaper.Yasuo Honda
-
Fix
in_order_ofraising when the column is a CTE reference.viralpraxis
-
Fix
content_columnsincluding composite primary key components.Only the first primary key column was excluded; now all primary key columns
are excluded.Kenta Ishizaki
-
Treat
remove_columnwith options but no type as irreversible.Previously,
remove_column(:table, :column, default: nil)would not raise
IrreversibleMigrationbecause the options hash was mistaken for a column
type.Kenta Ishizaki
-
Fix
counter_cache_columncrashing when:counter_cacheis given as a
Hash without a:columnkey.Kenta Ishizaki
-
Coerce
seedsanduse_metadata_tableto booleans inUrlConfig.When configured via
DATABASE_URL, these options were left as strings
instead of being coerced to booleans likereplicaanddatabase_tasks.Kenta Ishizaki
-
Fix
excluding(and itswithoutalias) to work with composite primary key
models. Records passed toexcludingare now matched by their full composite id
instead of being looked up by a single primary key column.Kenta Ishizaki
-
Fix
Relation#deleteraising on a single composite primary key id.Model.delete(id)now wraps a single composite id in an array before building
theWHEREclause, so a single record can be deleted by its composite id.Kenta Ishizaki
-
Fix reading a composite primary key after a partial
selectreturning the
raw value instead ofnilfor unselected key columns.The attribute defaults builder excluded only the single primary key column from
defaults; for composite primary keys it left the unselected key columns in the
defaults, sorecord.idreturned an array of raw column values instead of
[nil, nil]. All primary key columns are now excluded.Kenta Ishizaki
-
Fix
findwith an empty array on a composite primary key model returning the
argument array instead of[].Model.find([])now returns a fresh empty array for composite primary key
models, matching single-key models.Kenta Ishizaki
-
Fix
findwith an order clause and an offset past the end of the ids raising
RecordNotFoundinstead of returning an empty result.Kenta Ishizaki
-
Fix
in_order_ofdropping values that cannot be serialized for the column
instead of turning them into anIS NULLmatch.Out-of-range integers and unknown enum keys are now ignored rather than
silently matching rows withNULLin that column. When all requested values
are unrepresentable, the relation returns no rows instead of building an empty
CASEexpression.Kenta Ishizaki
-
Fix stale
finder_needs_type_condition?memo after the schema cache is reloaded.When an STI model's
typecolumn was removed and re-added (e.g. via a
migration) andreset_column_informationwas called, the cached
finder_needs_type_conditionvalue was not cleared, so queries could omit the
STI type condition. The memo is now reset onreload_schema_from_cache.Kenta Ishizaki
-
Fix PostgreSQL schema dump to qualify
enum_typewhen the same enum name exists
in different schemas.Previously the dumped
enum_typeused the bare type name, which could resolve to
the wrong enum in another schema. It now uses the schema-qualified name.fatkodima
-
Fix PostgreSQL index introspection to parse opclasses from another schema.
Index expressions using a schema-qualified opclass (e.g.
USING gin(position test_schema.gin_trgm_ops)) are now parsed correctly so the
opclass is captured without the schema prefix.Nicolas Vandenboegaerde
-
Fix
belongs_to:touchwith composite foreign keys.Touching the parent record when a
belongs_towith a composite foreign key
changes or is destroyed now correctly resolves the old and new parent by all
foreign key columns.Romulo Storel
-
Fix
add_indexcomment:option on a schema-qualified PostgreSQL table.The
COMMENT ON INDEXstatement now schema-qualifies the index name, so the
comment is applied to the index in the correct schema instead of raising.Tobias Egli
-
Fix
check_all_foreign_keys_valid!on PostgreSQL partitioned tables.The validation query previously matched constraints by name across all tables in
the schema, marking unrelated constraints (including partition children) as not
validated. It now scopes the update to the specific table.Alexis Andrieu
-
Revert stable sorting of columns and indexes in serialized schema caches.
SchemaCache#encode_withno longer sorts a table's columns and indexes by name
when writing the cache, restoring the pre-8.1 behavior.Jean Boussier
-
Fix
only_columnsto enumerate columns in theSELECTclause.Models using
only_columnswere generatingSELECT *instead of an explicit
column list, which could select columns that were meant to be excluded.sarub0b0
-
Fix
eager_loadwith a composite primary key and an explicitselect.The join dependency used the single primary key value to build aliases; for
composite primary keys it now uses the full array of primary key columns, so
eager loading with a customselectno longer drops the association records.fatkodima
-
Fix
find_signedwith a composite primary key.find_signednow wraps the decoded id in an array sofind_bymatches against
all primary key columns, instead of silently returningnil.Kenta Ishizaki
-
Fix
with_connection(prevent_permanent_checkout: true)clearing a sticky lease
that was already set bylease_connection.A
with_connectioncall withprevent_permanent_checkout: trueno longer resets
lease.stickyto its previous value when the connection was already sticky, so
the connection remains checked out after the block.Ben Sheldon
-
Fix
reset_countersto cast string ids to the primary key type.reset_counterscalled with a string id (the form ids take from request params)
failed to find the record for both single and composite primary keys. Each id is
now cast against its own column type.fatkodima
-
Fix
belongs_topresence validation for composite foreign keys.The required-association validation only checked the first foreign key column.
For composite foreign keys it now considers the association present only when
none of the foreign key columns arenil, and changed when any of them changed.Felix Descoteaux
-
Fix preloading a
belongs_towith a composite foreign key when some key columns
arenil.The preloader now skips owners whose composite key has any
nilcomponent
instead of issuing a query that matches unrelated rows.Rose Wiegley
-
Fix
belongs_toinverse matching with composite foreign keys.inversable?compared a single foreign key column against a single primary key,
sobelongs_toassociations with composite foreign keys never matched their
inverse. Foreign key and primary key values are now compared component by
component.Martin Samson
-
Fix
validate_table_length!to ignore the schema prefix on PostgreSQL.Schema-qualified table names (e.g.
"schema.very_long_table_name") were
incorrectly rejected as exceeding the table name length limit because the schema
prefix was counted. The schema is now stripped before checking the length.fatkodima
-
Fix passing Trilogy SSL options to
mysqlandmysqldumpcommands.Ngan Pham
-
Fix
keepalive: falseindatabase.ymlfalling back to the
600 second default.Joe Sak
-
Fix connection checkout blocking past the configured
checkout_timeoutwhile
waiting behind background connection maintenance.ConnectionPool#try_to_queue_for_background_connectionwaited up to a
hardcoded 100 seconds for a connection tied up in maintenance (e.g. a keepalive
ping), regardless of the pool's configuredcheckout_timeout. If maintenance
stalled (a slow or unresponsive database server), checkout could block for far
longer than the caller asked for.Joe Sak
-
Fix encrypted fixtures for JSON columns.
Encrypted fixture values were serialized twice: once by the encrypted
attribute type and again by the column type when the rows were inserted.
Forjson/jsonbcolumns this stored the encrypted payload as a JSON
string, which then failed to decrypt. The payload is now handed back in
the column's cast form so it round-trips through the column type.Carlos Daniel Pohlod
-
Fix performance regression in
method_missingfor virtual SELECT alias
attributes.Fixes #57183.
Hammad Khan
-
Column defaults are no longer eagerly deserialized.
Restore the Active Record 8.0 and older behavior.
Column defaults are now whatever is returned by the database, generally a string.This was changed in 8.1.0 to make the attribute API more consistent,
however it caused problems when the attribute type is later changed in the model.Typically, some databases treat boolean columns as small integers, ance once the
default integer is casted to a boolean, it's not longer possible to change the
attribute back into an integer in the model.Before:
Person.columns_hash["age"].default # => 0
After:
Person.columns_hash["age"].default # => "0"
See #58292.
Jean Boussier
-
Preserve the declared parent order when dumping PostgreSQL
INHERITStable options.The schema dumper read a table's inherited parents without an
ORDER BY, so the
INHERITS (...)clause inschema.rbcould be emitted in a nondeterministic order.
Parents are now ordered bypg_inherits.inhseqno.viralpraxis
-
Preserve SQLite partial and expression indexes when their stored SQL contains newlines.
Javi Ramírez
-
Only use multi statement for
SET TRANSACTION ISOLATION LEVEL; BEGINif
MySQL connection is configured to use multi statement.Eliseu Daroit, Hartley McGuire, Matthew Draper
-
Mark a connection unverified when a non-
StandardErrorinterrupts a query.A query interrupted by a non-
StandardError, such as a fiber scheduler's
cancel or aTimeout, leaves the connection desynced. Active Record
previously returned it to the pool still marked verified, so the next
checkout reused it and failed on a dead socket. The connection is now
marked unverified, so it re-verifies and reconnects before its next use.Eliseu Daroit
-
Fix
has_manyandhas_oneassociations on a new record returning an empty
result when the owner has a composite primary key, even when every primary
key column is populated.Jean-Samuel Aubry-Guzzi
-
Fix inverse association matching for
has_manyandhas_oneassociations
with association-specific composite primary keys.Hugo Vacher
-
Fix
ActiveRecord::Base.withto callObject#withwhen given a block.The class-level
withdelegates to the relation's CTE query method, which
does not accept a block. When a block is passed, it now delegates to
Object#withinstead, so it can be used to temporarily set attributes on
the class for the duration of the block.Janko Marohnić
-
Fix
serializewithcoder: ActiveRecord::Coders::JSONsilently double-encoding
a nativejson/jsonbcolumn.Kenta Ishizaki
-
Fix
update_all/delete_allignoringgroupandhaving, updating or
deleting every row in the table instead of only the rows that satisfy the
HAVINGclause.Kenta Ishizaki
-
Fix
ActiveRecord::Relation#cache_key/cache_versionfor a loaded collection
containing a record without a timestamp.Kenta Ishizaki
-
Fix model
filter_attributesto not add useless filters intoconfig.filter_parameters.Proc and Regexp filters would be improperly turned into string matchers.
Now they are skipped.Jonathan Calvert
-
Fix
ActiveRecord::MessagePackserialization raisingNoMethodError
for any record with a populatedtimecolumn, which made such records
uncacheable through the MessagePack cache serializer.Kenta Ishizaki
-
Fix replacing or clearing a polymorphic
has_oneleaving a stale type column
on the removed record.Kenta Ishizaki
-
Fix
accepts_nested_attributes_for:limitmiscounting a single-record hash.Kenta Ishizaki
-
Fix
rename_indexto preserve a partial index'sWHEREfor SQLite and older MySQL/MariaDB versions.Kenta Ishizaki
-
Fix PostgreSQL
foreign_keysreturning a corruptedto_tablefor a foreign key
that references a table in a quoted schema.Kenta Ishizaki
-
Fix grouped calculations (e.g.
count) grouped by abelongs_toassociation
that points to a composite primary key model.Book.group(:order).count, whereBook belongs_to :orderandOrderhas a
composite primary key, raisedArgumentError: Expected corresponding value for ["shop_id", "id"] to be an Array. The grouped result is now keyed by the
associated records as it already is for single-column keys.Kenta Ishizaki
-
Fix
has_many/has_one :throughassociations withdisable_joins: true
silently returning an empty result when the source points to a composite
primary key model.Kenta Ishizaki
-
Fix collection association
ids=writers (e.g.author.book_ids=) raising
ActiveRecord::RecordNotFoundfor existing records when a composite primary
key model is assigned string ids (the shape ids take from request params).Each id component is now cast against its own column type, instead of casting
the whole tuple against an array of column names, whichtype_for_attribute
can't resolve to a real type (so the cast was a no-op and the string ids
never matched the loaded records).Kenta Ishizaki
-
Fix
findwith multiple composite primary key ids passed as strings
silently returning[].Model.find([["1", "10"], ["1", "20"]])(the shape ids take when they come
from request parameters) returned an empty array instead of the records and
without raisingRecordNotFound. The ids were cast against the array of key
column names as a whole — which is a no-op — so the string tuples never
compared equal to the records' integer ids when ordering the result. Each
component is now cast against its own column type, matching the documented
coercion already performed for single-column keys.Kenta Ishizaki
-
Fix PostgreSQL
daterange/tsrange/tstzrangeschema dump producing
invalid Ruby.The schema dumper used to render range defaults via
Range#inspect, which
falls back toDate#inspect/Time#inspectfor the bounds. The resulting
schema.rbliteral (for exampledefault: Mon, 01 Jan 2024..Wed, 01 Jan 2025)
raised aSyntaxErrorondb:schema:load. The bounds are now rendered via
the subtype'stype_cast_for_schema, so date and timestamp range defaults
round-trip throughschema.rblike any other column.Kenta Ishizaki
-
Fix deadlock when pool-less connection materializes while fetching database
server version.Hartley McGuire
-
Fix PostgreSQL range columns corrupting bounds that contain a comma.
PostgreSQL::OID::Range#extract_boundssplit a range's textual
representation on the first comma, but PostgreSQL double-quotes any bound
that itself contains a comma (e.g. a range over a text subtype). A value
such as["a,b","c,d")was therefore split inside the first quoted bound
and read back with both endpoints corrupted. The split now skips over
double-quoted segments when locating the separating comma.Kenta Ishizaki
-
Fix store accessor
*_changeandsaved_change_to_*reporting a change
for unchanged keys.When one key of a
storecolumn changed, the generated<key>_changeand
saved_change_to_<key>methods returned a[value, value]pair for the
column's other keys too, even though their matching<key>_changed?/
saved_change_to_<key>?correctly returnedfalseand standard attribute
_change/saved_change_to_*methods returnnilwhen unchanged. The
methods now returnnilunless that specific key actually changed,
matching their predicate counterparts.Kenta Ishizaki
-
Reduce number of queries when introspecting MySQL/MariaDB tables.
A fix to support MariaDB function defaults caused the MySQL adapters to
issue one query per column when introspecting tables.Now it only issue a single extra query per table, and only when using MariaDB.
Iliana Hadzhiatanasova
-
Fully qualify query criterias in
has_and_belongs_to_manyassociations.Ensure that scopes with the same column name but in different tables aren't lost
when following an HABTM association.Philip Maina
-
Fix Active Record Pool Reaper thread leak after
Parallelization#shutdown.After parallelized test runs, the parent process leaked the Active Record Pool
Reaper thread, holding open connection pools and file descriptors for up to
reaping_frequencyseconds (or indefinitely if never reaped).Three fixes:
Parallelization#shutdownnow callsrun_cleanup_hooks;
Active Record registers a cleanup hook that discards all connection pools; and
ConnectionPool#discard!now callsReaper.discard_pool, which immediately
kills and joins the reaper thread when no pools remain at that frequency.Ruy Rocha
-
Fix duplicate
WHEREconditions increate_or_find_by.When
create_or_find_bycatches aRecordNotUniqueerror and retries the query, it now usesrewhereandtake!to prevent duplicating existing scope conditions.Yavor Dashev
-
Fix
ActiveRecord::QueryMethods#in_order_ofwhen passing an out-of-range IntegerTo match the behavior of the
Enumerableversion,in_order_ofnow ignores an out-of-range Integer.tejanium
-
Revert alphabetical sorting of table columns inside
schema.rb.Alphabetical sorting of table columns inside the schema creates improper production tables when using
db:prepare.Bert McCutchen
-
Fix
strict_loadingviolations ignored when usingpluckJohnson Chan
-
Fix incorrect callback execution order when
config.active_record.run_after_transaction_callbacks_in_order_defined = true
and usingafter_commitandafter_rollbackcallbacks withprepend: true.Joshua Young
-
Fix
becomesto preservemarked_for_destruction?.Vincent Robert
-
MySQL error 1046 (
ER_NO_DB_ERROR: No database selected) is now retryable as aConnectionFailedexceptionClay Harmon
Action View
-
Fix non-ASCII strict locals defaults rendering as mojibake.
When a template declared a non-ASCII default in its
locals:magic comment
and its body was ASCII-only, the handler returned ASCII-8BIT code and the
compiled method definition was retagged with it, corrupting the default.Carlos Daniel Pohlod
-
Fix the
:rubyrender tracker not being registered for ERB templates when
eager_loadis enabled.Gabriel Quaresma
-
Fix
Encoding::CompatibilityErrorwhen digesting templates with non-ASCII
content viaDependencyTracker::RubyTracker.File-backed templates are loaded as ASCII-8BIT.
RubyTrackernow passes
template.encode!to the handler (matchingTemplate#compiled_source) so
handlers such as Haml/Temple can concatenate static UTF-8 strings without
raising. Fixes #58203.Edil Talantbek uulu
-
Fix
week_fieldto not emit invalid week strings at ISO year boundaries.Kenta Ishizaki
-
Fix
ActionView::TestCase#renderto resetrendered.
The behavior was changed when memoization was added in #51093. Now it once again conforms to the documentation.Jeroen Versteeg
-
Fix
FormBuilder#to_partial_pathreturningnilfor subclasses whose
name does not end inBuilder.Kenta Ishizaki
-
Fix
collection_radio_buttonsandcollection_check_boxesgenerating
a labelforattribute that does not match the inputidwhen a
collection value isnil.Kenta Ishizaki
Action Pack
-
Fix the debug error page to not attempt to read source fragments from
directory paths.Marco Roth
-
Apply source value mappings to dynamic Permissions Policy sources.
Dynamic Permissions Policy sources (procs) now have source mappings applied
to their resolved values, the same as static sources.Kenta Ishizaki
-
Allow
ActionDispatch::Http::URL.path_forwithtrailing_slash: trueand a
blank path to accept query params and an anchor.Previously the blank path used a frozen
"/", which raised aFrozenError
when appending the query string.Kenta Ishizaki
-
Avoid mutating the
paramshash passed toActionDispatch::Http::URL.url_for.Kenta Ishizaki
-
Honor falsy values (e.g.
format: false,anchor: false) passed in the
deprecated positional-hash form of routing DSL methods.Previously,
falsevalues were silently dropped without emitting a
deprecation warning, causing the deprecated hash form to produce different
routes than the keyword form.Kenta Ishizaki
-
Honor the deprecated
namespacehash:path,:shallow_path, and
:shallow_prefixoptions when passed asfalse.Kenta Ishizaki
-
Fix the deprecated
scopehash:exceptoption to apply toexcept
instead ofonly.Kenta Ishizaki
-
Reject malformed hosts with extra ports in
ActionDispatch::HostAuthorization.When an allowed host is configured with an explicit port, a
Hostheader
with an additional port (e.g.www.example.com:80:80) is no longer accepted.Andrii Furmanets
-
Fix
url_forto leave out an optional part of a route when its value is a
blank string, the same way it already does fornil.Before, the blank string ended up in the path, producing a URL the route
itself cannot match:get "(/locale/:locale)/products(/:id)", to: "products#show" url_for(controller: "products", action: "show", locale: "", id: 123) # Before: "/locale//products/123" # After: "/products/123"
Blank strings for required parameters behave as before.
Carl Dawson
-
Fix path normalization to handle mixed-case percent-encoding.
Andrii Furmanets
-
Avoid loading
ActionController::Liveearly in initializer, and introduce
action_controller_liveload hook.Adrianna Chang
-
Set the browser binary when preloading the Selenium driver for system tests.
Selenium 4.45 stopped setting it as a side effect of getting the driver path,
causing tests to fail with "cannot find Chrome binary".Titus Fortner
-
Fix
Session::CacheStoreto not generate a new session after dropping the current one.Kenta Ishizaki
-
Parse all three HTTP-date formats in the
If-Modified-Sincerequest header.If-Modified-Sincecarries an HTTP-date, which RFC 9110 allows in any of
three formats (IMF-fixdate, RFC 850, or asctime), and requires recipients to
accept all three. The header was parsed withTime.rfc2822, which only
accepts the IMF-fixdate format, and the parse failure was swallowed — so a
conditionalGETusing an RFC 850 or asctime date silently failed to produce
a304 Not Modifiedand re-sent the full response. It is now parsed with
Time.httpdate, consistent with howLast-ModifiedandDateare read.Kenta Ishizaki
-
Fix response steam buffers compatibility with
IO.copy_stream.IO.copy_stream(src, response.stream)raisedTypeError: no implicit conversion of Array into IntegerbecauseBuffer#writereturned the
buffer array instead of an Integer (bytes written). Additionally, the
written data could be silently corrupted becauseIO.copy_stream
reuses its internal string buffer afterwritereturns — storing a
reference withoutdupmeant the buffered content was later mutated.Both
ActionDispatch::Response::Buffer#writeand
ActionController::Live::Buffer#writeare affected.Gabriel Quaresma
Active Job
-
Fix
retry_jobto preservewait_until,queue, andpriorityoptions when
enqueue_after_transaction_commitdefers the enqueue.Said Kaldybaev
-
Clear a stale
enqueue_errorwhenperform_all_latersuccessfully re-enqueues a job.Kenta Ishizaki
-
Clear
enqueue_errorwhen a job is successfully re-enqueued viaenqueue.Kenta Ishizaki
-
Fix
resume_jobnot receiving the exception when resuming a continuation after
an error, causingexception_executionsto not be recorded correctly.Kenta Ishizaki
-
Fix
ActiveJob.perform_all_laternot being available untilActiveJob::Enqueuing
was autoloaded.fatkodima
Action Mailer
-
Fix
ActionMailer.deliver_all_laternot being available until
ActionMailer::MessageDeliverywas autoloaded.fatkodima
-
Fix
ActionMailer::Base.mailnot returning aMessageDeliveryin Rails 8.1+.Andrii Furmanets
Action Cable
-
Allow
redis-rb6 in the Action Cable Redis subscription adapter.Shuta Mugikura
-
Fix the PostgreSQL subscription adapter dropping broadcasts to long multibyte stream names.
PostgreSQL identifiers are limited to 63 bytes, and the adapter hashes any
name over that limit to avoid silent truncation. The length check was done on
character count rather than byte size, so a multibyte stream name with 63 or
fewer characters but more than 63 bytes was silently truncated by PostgreSQL.Kenta Ishizaki
Active Storage
-
Warn instead of aborting boot when
image_processing2.x is installed withoutruby-vips
ormini_magick.Both gems became soft dependencies in
image_processing2.0, and theLoadErrorraised for
a missing one names that gem instead ofimage_processing. Active Storage did not recognize
the message, so it re-raised rather than logging its usual warning.Fixes #58413.
Janko Marohnić
-
Fix
MirrorService#mirrorlosing blob metadata when copying to mirrors.Mirrored copies on S3, Azure, and GCS were served as
application/octet-stream
becausecontent_type,filename,disposition, andcustom_metadatawere
dropped. Forward the blob'sservice_metadatato each mirror's upload.Fixes #57270.
Maksim Romanov + Andrii Furmanets
-
Prevent
ActiveStorage.touch_attachment_records = falsefrom crashing the attachment of a Blob.When
ActiveStorage.touch_attachment_recordswas set tofalse, attaching a existing Blob to a Record
would raise an error. This is now fixed.Edouard Chin
-
Fix
MirrorService#mirrorraisingActiveStorage::IntegrityErrorwhen
mirroring without a checksum (e.g.,track_variants: false).Denis Savchuk
-
Preserve attachment changes when converting record to another class using STI.
fatkodima
-
Correct unexpected behavior resulting from dependent: :purge when using
has_one_attached or has_many_attached. Fixes #36423.Mark Oveson
-
Define
as_jsononActiveStorage::Attached::OneandActiveStorage::Attached::Many.The proxies hold a back-reference to the owning record in
@record. Without an explicit
as_json, the defaultObject#as_jsonfall back serializedinstance_values, which made
record.to_jsonrecurse infinitely whenever the attached name collided with a model
attribute (e.g. anignored_columnscolumn brought back byselect('*')).Attached::One#as_jsonnow returns the attachment record's JSON when attached andnil
otherwise.Attached::Many#as_jsonreturns the attachment records' JSON as an array.Renxiang Cai
-
Fix Rails hanging when generating video previews
When Rails runs in a background process group, ffmpeg's attempt to configure the terminal for
interactive input would send SIGTTOU to the Rails process, suspending it indefinitely.Fixed by explicitly passing /dev/null to ffmpeg's stdin.
Jonathan del Strother
Action Mailbox
- No changes.
Action Text
- No changes.
Railties
-
Include the offending value in the
secret_key_base=error message.Jean Boussier
-
Load database config when a connection is absent from the shared section.
database_configurationno longer raisesNoMethodErrorwhen a shared
config section is missing a subsection for a particular connection name.Kenta Ishizaki
-
Round-trip the
null: falseattribute modifier inGeneratedAttribute#to_s.rails generatenow emits the!modifier for attributes withnull: false,
so the generated command string can be used to regenerate the same migration.Kenta Ishizaki
-
Fix infinite route reload when
after_routes_loadedhooks access routes.The
:loadingstate is now held acrossafter_routes_loadedhooks, so a
hook that touches routes no longer triggers a redundant reload.Chedli Bourguiba
-
Fix
LazyRouteSetthrashing whenurl_helpersare included intoObject.method_missingandrespond_to_missing?now only trigger a route reload
for methods ending in_pathor_url, preventing everyrespond_to?
call from re-entering the route loader.Chedli Bourguiba
-
Add
RoutesReloader#loadedto check whether routes have been loaded.Rafael Mendonça França
-
Mark routes as loaded when the routes reloader executes standalone.
RoutesReloader#executenow sets the load state toloaded, so calling
it directly (outside ofexecute_unless_loaded) no longer leaves the
reloader in a state where routes are considered unloaded.Kenta Ishizaki
-
Make mounted route helpers (e.g.
main_app, engine mount proxies) trigger
the lazy route load instead of raisingNoMethodErrorwhen called before
routes are drawn.Named url helpers already loaded routes on demand, but mounted helpers are
only defined whenmountruns during the route draw, so calling one first
(in the console or a test) failed until something else drew the routes.Abdelkader Boudih
-
Make lazy route loading thread-safe.
Since routes are drawn on the first request in environments where
config.eager_loadisfalse(development and test by default),
concurrent first requests could dispatch against an empty or half-drawn
route set, resulting in a 404 for a perfectly valid route. Route drawing
is now synchronized: concurrent requests wait for the initial draw to
complete and are then dispatched against the fully drawn route set.grk
-
Validate subcommand in
rails plugincommand.rails plugin foo barsilently ignored the invalid subcommand "foo"
and proceeded to create a plugin named "bar". Now it prints an error
and exits with status 1.Fixes #57430.
Ruy Rocha
-
Prevent the internal development welcome route from being duplicated on route reloads.
Elliot Temple
Guides
- No changes.