Skip to content

Releases: rails/rails

8.1.1

28 Oct 23:46
v8.1.1
90a1eaa

Choose a tag to compare

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Respect remove_hidden_field_autocomplete config in form builder hidden_field.

    Rafael Mendonça França

Action Pack

  • Allow methods starting with underscore to be action methods.

    Disallowing methods starting with an underscore from being action methods
    was an unintended side effect of the performance optimization in
    207a254.

    Fixes #55985.

    Rafael Mendonça França

Active Job

  • Only index new serializers.

    Jesse Sharps

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Do not assume and force SSL in production by default when using Kamal, to allow for out of the box Kamal deployments.

    It is still recommended to assume and force SSL in production as soon as you can.

    Jerome Dalbert

Guides

  • No changes.

8.0.4

28 Oct 23:43
v8.0.4
624fe3c

Choose a tag to compare

Active Support

  • Fix Enumerable#sole to return the full tuple instead of just the first element of the tuple.

    Olivier Bellone

  • Fix parallel tests hanging when worker processes die abruptly.

    Previously, if a worker process was killed (e.g., OOM killed, kill -9) during parallel
    test execution, the test suite would hang forever waiting for the dead worker.

    Joshua Young

  • Fix NameError when class_attribute is defined on instance singleton classes.

    Previously, calling class_attribute on an instance's singleton class would raise
    a NameError when accessing the attribute through the instance.

    object = MyClass.new
    object.singleton_class.class_attribute :foo, default: "bar"
    object.foo # previously raised NameError, now returns "bar"

    Joshua Young

Active Model

  • No changes.

Active Record

  • Fix SQLite3 data loss during table alterations with CASCADE foreign keys.

    When altering a table in SQLite3 that is referenced by child tables with
    ON DELETE CASCADE foreign keys, ActiveRecord would silently delete all
    data from the child tables. This occurred because SQLite requires table
    recreation for schema changes, and during this process the original table
    is temporarily dropped, triggering CASCADE deletes on child tables.

    The root cause was incorrect ordering of operations. The original code
    wrapped disable_referential_integrity inside a transaction, but
    PRAGMA foreign_keys cannot be modified inside a transaction in SQLite -
    attempting to do so simply has no effect. This meant foreign keys remained
    enabled during table recreation, causing CASCADE deletes to fire.

    The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
    procedure: disable_referential_integrity now wraps the transaction instead
    of being wrapped by it. This ensures foreign keys are properly disabled
    before the transaction starts and re-enabled after it commits, preventing
    CASCADE deletes while maintaining data integrity through atomic transactions.

    Ruy Rocha

  • Add support for bound SQL literals in CTEs.

    Nicolas Bachschmidt

  • Fix belongs_to associations not to clear the entire composite primary key.

    When clearing a belongs_to association that references a model with composite primary key,
    only the optional part of the key should be cleared.

    zzak

  • Fix invalid records being autosaved when distantly associated records are marked for deletion.

    Ian Terrell, axlekb AB

Action View

  • Restore add_default_name_and_id method.

    Hartley McGuire

Action Pack

  • Submit test requests using as: :html with Content-Type: x-www-form-urlencoded

    Sean Doyle

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

7.2.3

28 Oct 23:24
v7.2.3
bb2bdef

Choose a tag to compare

Active Support

  • Fix Enumerable#sole to return the full tuple instead of just the first element of the tuple.

    Olivier Bellone

  • Fix parallel tests hanging when worker processes die abruptly.

    Previously, if a worker process was killed (e.g., OOM killed, kill -9) during parallel
    test execution, the test suite would hang forever waiting for the dead worker.

    Joshua Young

  • ActiveSupport::FileUpdateChecker does not depend on Time.now to prevent unnecessary reloads with time travel test helpers

    Jan Grodowski

  • Fix ActiveSupport::BroadcastLogger from executing a block argument for each logger (tagged, info, etc.).

    Jared Armstrong

  • Fix ActiveSupport::HashWithIndifferentAccess#transform_keys! removing defaults.

    Hartley McGuire

  • Fix ActiveSupport::HashWithIndifferentAccess#tranform_keys! to handle collisions.

    If the transformation would result in a key equal to another not yet transformed one,
    it would result in keys being lost.

    Before:

    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"c" => 1}

    After:

    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"c" => 1, "d" => 2}

    Jason T Johnson, Jean Boussier

  • Fix ActiveSupport::Cache::MemCacheStore#read_multi to handle network errors.

    This method specifically wasn't handling network errors like other codepaths.

    Alessandro Dal Grande

  • Fix Active Support Cache fetch_multi when local store is active.

    fetch_multi now properly yield to the provided block for missing entries
    that have been recorded as such in the local store.

    Jean Boussier

  • Fix execution wrapping to report all exceptions, including Exception.

    If a more serious error like SystemStackError or NoMemoryError happens,
    the error reporter should be able to report these kinds of exceptions.

    Gannon McGibbon

  • Fix RedisCacheStore and MemCacheStore to also handle connection pool related errors.

    These errors are rescued and reported to Rails.error.

    Jean Boussier

  • Fix ActiveSupport::Cache#read_multi to respect version expiry when using local cache.

    zzak

  • Fix ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor configuration of on_rotation callback.

    verifier.rotate(old_secret).on_rotation { ... }

    Now both work as documented.

    Jean Boussier

  • Fix ActiveSupport::MessageVerifier to always be able to verify both URL-safe and URL-unsafe payloads.

    This is to allow transitioning seemlessly from either configuration without immediately invalidating
    all previously generated signed messages.

    Jean Boussier, Florent Beaurain, Ali Sepehri

  • Fix cache.fetch to honor the provided expiry when :race_condition_ttl is used.

    cache.fetch("key", expires_in: 1.hour, race_condition_ttl: 5.second) do
      "something"
    end

    In the above example, the final cache entry would have a 10 seconds TTL instead
    of the requested 1 hour.

    Dhia

  • Better handle procs with splat arguments in set_callback.

    Radamés Roriz

  • Fix String#mb_chars to not mutate the receiver.

    Previously it would call force_encoding on the receiver,
    now it dups the receiver first.

    Jean Boussier

  • Improve ErrorSubscriber to also mark error causes as reported.

    This avoid some cases of errors being reported twice, notably in views because of how
    errors are wrapped in ActionView::Template::Error.

    Jean Boussier

  • Fix Module#module_parent_name to return the correct name after the module has been named.

    When called on an anonymous module, the return value wouldn't change after the module was given a name
    later by being assigned to a constant.

    mod = Module.new
    mod.module_parent_name # => "Object"
    MyModule::Something = mod
    mod.module_parent_name # => "MyModule"

    Jean Boussier

  • Fix a bug in ERB::Util.tokenize that causes incorrect tokenization when ERB tags are preceeded by multibyte characters.

    Martin Emde

Active Model

  • Fix has_secure_password to perform confirmation validation of the password even when blank.

    The validation was incorrectly skipped when the password only contained whitespace characters.

    Fabio Sangiovanni

  • Handle missing attributes for ActiveModel::Translation#human_attribute_name.

    zzak

  • Fix ActiveModel::AttributeAssignment#assign_attributes to accept objects without each.

    Kouhei Yanagita

Active Record

  • Fix SQLite3 data loss during table alterations with CASCADE foreign keys.

    When altering a table in SQLite3 that is referenced by child tables with
    ON DELETE CASCADE foreign keys, ActiveRecord would silently delete all
    data from the child tables. This occurred because SQLite requires table
    recreation for schema changes, and during this process the original table
    is temporarily dropped, triggering CASCADE deletes on child tables.

    The root cause was incorrect ordering of operations. The original code
    wrapped disable_referential_integrity inside a transaction, but
    PRAGMA foreign_keys cannot be modified inside a transaction in SQLite -
    attempting to do so simply has no effect. This meant foreign keys remained
    enabled during table recreation, causing CASCADE deletes to fire.

    The fix reverses the order to follow the official SQLite 12-step ALTER TABLE
    procedure: disable_referential_integrity now wraps the transaction instead
    of being wrapped by it. This ensures foreign keys are properly disabled
    before the transaction starts and re-enabled after it commits, preventing
    CASCADE deletes while maintaining data integrity through atomic transactions.

    Ruy Rocha

  • Fix belongs_to associations not to clear the entire composite primary key.

    When clearing a belongs_to association that references a model with composite primary key,
    only the optional part of the key should be cleared.

    zzak

  • Fix invalid records being autosaved when distantly associated records are marked for deletion.

    Ian Terrell, axlekb AB

  • Prevent persisting invalid record.

    Edouard Chin

  • Fix count with group by qualified name on loaded relation.

    Ryuta Kamizono

  • Fix sum with qualified name on loaded relation.

    Chris Gunther

  • Fix prepared statements on mysql2 adapter.

    Jean Boussier

  • Fix query cache for pinned connections in multi threaded transactional tests.

    When a pinned connection is used across separate threads, they now use a separate cache store
    for each thread.

    This improve accuracy of system tests, and any test using multiple threads.

    Heinrich Lee Yu, Jean Boussier

  • Don't add id_value attribute alias when attribute/column with that name already exists.

    Rob Lewis

  • Fix false positive change detection involving STI and polymorhic has one relationships.

    Polymorphic has_one relationships would always be considered changed when defined in a STI child
    class, causing nedless extra autosaves.

    David Fritsch

  • Fix stale associaton detection for polymophic belong_to.

    Florent Beaurain, Thomas Crambert

  • Fix removal of PostgreSQL version comments in structure.sql for latest PostgreSQL versions which include \restrict.

    Brendan Weibrecht

  • Fix #merge with #or or #and and a mixture of attributes and SQL strings resulting in an incorrect query.

    base = Comment.joins(:post).where(user_id: 1).where("recent = 1")
    puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql

    Before:

    SELECT "comments".* FROM "comments"
    INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
    WHERE (recent = 1)
    AND (
      "comments"."user_id" = 1
      AND (recent = 1)
      AND "comments"."draft" = 1
      OR "posts"."archived" = 1
    )

    After:

    SELECT "comments".* FROM "comments"
    INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
    WHERE "comments"."user_id" = 1
    AND (recent = 1)
    AND (
      "comments"."user_id" = 1
      AND (recent = 1)
      AND "comments"."draft" = 1
      OR "posts"."archived" = 1
    )

    Joshua Young

  • Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys.

    fatkodima

  • Fix annotate comments to propagate to update_all/delete_all.

    fatkodima

  • Fix checking whether an unpersisted record is include?d in a strictly
    loaded has_and_belongs_to_many association.

    Hartley McGuire

  • Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys.

    fatkodima

  • create_or_find_by will now correctly rollback a transaction.

    When using create_or_find_by, raising a ActiveRecord::Rollback error
    in a after_save callback had no effect, the transaction was committed
    and a record created.

    Edouard Chin

  • Gracefully handle Timeout.timeout firing during connection configuration.

    Use of Timeout.timeout could result in improperly initialized database connection.

    This could lead to a partially configured connection being used, resulting in various exceptions,
    the most common being with the PostgreSQLAdapter raising undefined method 'key?' for nil
    or TypeError: wrong argument type nil (expected PG::TypeMap).

...

Read more

7.1.6

28 Oct 23:19
v7.1.6
ffcbf6f

Choose a tag to compare

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Gracefully handle Timeout.timeout firing during connection configuration.

    Use of Timeout.timeout could result in improperly initialized database connection.

    This could lead to a partially configured connection being used, resulting in various exceptions,
    the most common being with the PostgreSQLAdapter raising undefined method key?' for nilorTypeError: wrong argument type nil (expected PG::TypeMap)`.

    Jean Boussier

  • Fix error handling during connection configuration.

    Active Record wasn't properly handling errors during the connection configuration phase.
    This could lead to a partially configured connection being used, resulting in various exceptions,
    the most common being with the PostgreSQLAdapter raising undefined method key?' for nilorTypeError: wrong argument type nil (expected PG::TypeMap)`.

    Jean Boussier

  • Fix prepared statements on mysql2 adapter.

    Jean Boussier

  • Fix a race condition in ActiveRecord::Base#method_missing when lazily defining attributes.

    If multiple thread were concurrently triggering attribute definition on the same model,
    it could result in a NoMethodError being raised.

    Jean Boussier

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • Fixed compatibility with redis gem 5.4.1

    Jean Boussier

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

7.0.10

28 Oct 23:12
v7.0.10
f4321f7

Choose a tag to compare

7.0.9

28 Oct 23:02
v7.0.9
1a5613e

Choose a tag to compare

Active Support

  • Fix ActiveSupport::Notifications.publish_event to preserve units.

    This solves the incorrect reporting of time spent running Active Record
    asynchronous queries (by a factor 1000).

    Jean Boussier

  • Fix ActiveSupport::Deprecation to handle blaming generated code

    Jean Boussier, fatkodima

  • Fix #to_fs(:human_size) to correctly work with negative numbers.

    Earlopain

  • Add bigdecimal as Active Support dependency that is a bundled gem candidate for Ruby 3.4.

    bigdecimal 3.1.4 or higher version will be installed.
    Ruby 2.7 and 3.0 users who want bigdecimal version 2.0.0 or 3.0.0 behavior as a default gem,
    pin the bigdecimal version in your application Gemfile.

    Koichi ITO

  • Ensure {down,up}case_first returns non-frozen string.

    Jonathan Hefner

  • Add drb, mutex_m and base64 that are bundled gem candidates for Ruby 3.4

    Yasuo Honda

  • Fix delete_matched for file cache store to work with keys longer than the
    max filename size.

    fatkodima and Jonathan Hefner

  • Fix MemoryStore to prevent race conditions when incrementing or decrementing.

    Pierre Jambet

  • Fix MemoryStore to preserve entries TTL when incrementing or decrementing

    This is to be more consistent with how MemCachedStore and RedisCacheStore behaves.

    Jean Boussier

  • NumberHelper: handle objects responding to_d.

    fatkodima

  • NumberHelper: handle very large numbers.

    Alex Ghiculescu, fatkodima

  • Fix Range#overlaps? not taking empty ranges into account on Ruby < 3.3

    Nobuyoshi Nakada, Shouichi Kamiya, Hartley McGuire

Active Model

  • No changes.

Active Record

  • Fix an issue that could cause database connection leaks

    If Active Record successfully connected to the database, but then failed
    to read the server informations, the connection would be leaked until the
    Ruby garbage collector triggers.

    Jean Boussier

  • Fix single quote escapes on default generated MySQL columns

    MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.

    Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.

    This would result in issues when importing the schema on a fresh instance of a MySQL database.

    Now, the string will not be escaped and will be valid Ruby upon importing of the schema.

    Yash Kapadia

  • Fix Relation#transaction to not apply a default scope

    The method was incorrectly setting a default scope around its block:

    Post.where(published: true).transaction do
      Post.count # SELECT COUNT(*) FROM posts WHERE published = FALSE;
    end

    Jean Boussier

  • Fix renaming primary key index when renaming a table with a UUID primary key
    in PostgreSQL.

    fatkodima

  • Fix where(field: values) queries when field is a serialized attribute
    (for example, when field uses ActiveRecord::Base.serialize or is a JSON
    column).

    João Alves

  • Don't mark Float::INFINITY as changed when reassigning it

    When saving a record with a float infinite value, it shouldn't mark as changed

    Maicol Bentancor

  • ActiveRecord::Base.table_name now returns nil instead of raising
    "undefined method abstract_class? for Object:Class".

    a5-stable

  • Fix upserting for custom :on_duplicate and :unique_by consisting of all
    inserts keys.

    fatkodima

  • Fix NoMethodError when casting a PostgreSQL money value that uses a
    comma as its radix point and has no leading currency symbol. For example,
    when casting "3,50".

    Andreas Reischuck and Jonathan Hefner

  • Fix duplicate quoting for check constraint expressions in schema dump when using MySQL

    A check constraint with an expression, that already contains quotes, lead to an invalid schema
    dump with the mysql2 adapter.

    Fixes #42424.

    Felix Tscheulin

  • Fix MySQL expression index dumping with escaped quotes.

    fatkodima

  • Fix uniqueness validation on association not using overridden primary key.

    fatkodima

Action View

  • Fix the number_to_human_size view helper to correctly work with negative numbers.

    Earlopain

Action Pack

  • Fix ActionDispatch::Executor middleware to report errors handled by ActionDispatch::ShowExceptions.

    In the default production environment, ShowExceptions rescue uncaught errors
    and returns a response. Because if this the executor wouldn't report production
    errors with the default Rails configuration.

    Jean Boussier

  • Add racc as a dependency since it will become a bundled gem in Ruby 3.4.0

    Hartley McGuire

Active Job

  • Preserve the serialized timezone when deserializing ActiveSupport::TimeWithZone arguments.

    Joshua Young

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Fix ActiveStorage::Representations::ProxyController not returning the proper
    preview image variant for previewable files.

    Chedli Bourguiba

  • Make untracked variants obey config.active_storage.content_types_to_serve_as_binary
    and config.active_storage.content_types_allowed_inline.

    Chedli Bourguiba and Jonathan Hefner

  • Fix direct upload forms when submit button contains nested elements.

    Marc Köhlbrugge

  • Prevent ActiveRecord::StrictLoadingViolationError when strict loading is
    enabled and the variant of an Active Storage preview has already been
    processed (for example, by calling ActiveStorage::Preview#url).

    Jonathan Hefner

  • Fix variants not included when eager loading multiple records containing a single attachment

    When using the with_attached_#{name} scope for a has_one_attached relation,
    attachment variants were not eagerly loaded.

    Russell Porter

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

8.1.0

22 Oct 00:35
v8.1.0
1cdd190

Choose a tag to compare

Active Support

  • Remove deprecated passing a Time object to Time#since.

    Rafael Mendonça França

  • Remove deprecated Benchmark.ms method. It is now defined in the benchmark gem.

    Rafael Mendonça França

  • Remove deprecated addition for Time instances with ActiveSupport::TimeWithZone.

    Rafael Mendonça França

  • Remove deprecated support for to_time to preserve the system local time. It will now always preserve the receiver
    timezone.

    Rafael Mendonça França

  • Deprecate config.active_support.to_time_preserves_timezone.

    Rafael Mendonça França

  • Standardize event name formatting in assert_event_reported error messages.

    The event name in failure messages now uses .inspect (e.g., name: "user.created")
    to match assert_events_reported and provide type clarity between strings and symbols.
    This only affects tests that assert on the failure message format itself.

    George Ma

  • Fix Enumerable#sole to return the full tuple instead of just the first element of the tuple.

    Olivier Bellone

  • Fix parallel tests hanging when worker processes die abruptly.

    Previously, if a worker process was killed (e.g., OOM killed, kill -9) during parallel
    test execution, the test suite would hang forever waiting for the dead worker.

    Joshua Young

  • Add config.active_support.escape_js_separators_in_json.

    Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.

    Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
    As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.

    Étienne Barrié, Jean Boussier

  • Fix NameError when class_attribute is defined on instance singleton classes.

    Previously, calling class_attribute on an instance's singleton class would raise
    a NameError when accessing the attribute through the instance.

    object = MyClass.new
    object.singleton_class.class_attribute :foo, default: "bar"
    object.foo # previously raised NameError, now returns "bar"

    Joshua Young

  • Introduce ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting
    to enable event reporter debug mode in tests.

    The previous way to enable debug mode is by using #with_debug on the
    event reporter itself, which is too verbose. This new helper will help
    clear up any confusion on how to test debug events.

    Gannon McGibbon

  • Add ActiveSupport::StructuredEventSubscriber for consuming notifications and
    emitting structured event logs. Events may be emitted with the #emit_event
    or #emit_debug_event methods.

    class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber
      def notification(event)
        emit_event("my.notification", data: 1)
      end
    end

    Adrianna Chang

  • ActiveSupport::FileUpdateChecker does not depend on Time.now to prevent unecessary reloads with time travel test helpers

    Jan Grodowski

  • Add ActiveSupport::Cache::Store#namespace= and #namespace.

    Can be used as an alternative to Store#clear in some situations such as parallel
    testing.

    Nick Schwaderer

  • Create parallel_worker_id helper for running parallel tests. This allows users to
    know which worker they are currently running in.

    Nick Schwaderer

  • Make the cache of ActiveSupport::Cache::Strategy::LocalCache::Middleware updatable.

    If the cache client at Rails.cache of a booted application changes, the corresponding
    mounted middleware needs to update in order for request-local caches to be setup properly.
    Otherwise, redundant cache operations will erroneously hit the datastore.

    Gannon McGibbon

  • Add assert_events_reported test helper for ActiveSupport::EventReporter.

    This new assertion allows testing multiple events in a single block, regardless of order:

    assert_events_reported([
      { name: "user.created", payload: { id: 123 } },
      { name: "email.sent", payload: { to: "[email protected]" } }
    ]) do
      create_user_and_send_welcome_email
    end

    George Ma

  • Add ActiveSupport::TimeZone#standard_name method.

    zone = ActiveSupport::TimeZone['Hawaii']
    # Old way
    ActiveSupport::TimeZone::MAPPING[zone.name]
    # New way
    zone.standard_name # => 'Pacific/Honolulu'

    Bogdan Gusiev

  • Add Structured Event Reporter, accessible via Rails.event.

    The Event Reporter provides a unified interface for producing structured events in Rails
    applications:

    Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")

    It supports adding tags to events:

    Rails.event.tagged("graphql") do
      # Event includes tags: { graphql: true }
      Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")
    end

    As well as context:

    # All events will contain context: {request_id: "abc123", shop_id: 456}
    Rails.event.set_context(request_id: "abc123", shop_id: 456)

    Events are emitted to subscribers. Applications register subscribers to
    control how events are serialized and emitted. Subscribers must implement
    an #emit method, which receives the event hash:

    class LogSubscriber
      def emit(event)
        payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
        source_location = event[:source_location]
        log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
        Rails.logger.info(log)
      end
    end

    Adrianna Chang

  • Make ActiveSupport::Logger #freeze-friendly.

    Joshua Young

  • Make ActiveSupport::Gzip.compress deterministic based on input.

    ActiveSupport::Gzip.compress used to include a timestamp in the output,
    causing consecutive calls with the same input data to have different output
    if called during different seconds. It now always sets the timestamp to 0
    so that the output is identical for any given input.

    Rob Brackett

  • Given an array of Thread::Backtrace::Location objects, the new method
    ActiveSupport::BacktraceCleaner#clean_locations returns an array with the
    clean ones:

    clean_locations = backtrace_cleaner.clean_locations(caller_locations)

    Filters and silencers receive strings as usual. However, the path
    attributes of the locations in the returned array are the original,
    unfiltered ones, since locations are immutable.

    Xavier Noria

  • Improve CurrentAttributes and ExecutionContext state managment in test cases.

    Previously these two global state would be entirely cleared out whenever calling
    into code that is wrapped by the Rails executor, typically Action Controller or
    Active Job helpers:

    test "#index works" do
      CurrentUser.id = 42
      get :index
      CurrentUser.id == nil
    end

    Now re-entering the executor properly save and restore that state.

    Jean Boussier

  • The new method ActiveSupport::BacktraceCleaner#first_clean_location
    returns the first clean location of the caller's call stack, or nil.
    Locations are Thread::Backtrace::Location objects. Useful when you want to
    report the application-level location where something happened as an object.

    Xavier Noria

  • FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.

    Ermolaev Andrey, zzak

  • The new method ActiveSupport::BacktraceCleaner#first_clean_frame returns
    the first clean frame of the caller's backtrace, or nil. Useful when you
    want to report the application-level frame where something happened as a
    string.

    Xavier Noria

  • Always clear CurrentAttributes instances.

    Previously CurrentAttributes instance would be reset at the end of requests.
    Meaning its attributes would be re-initialized.

    This is problematic because it assume these objects don't hold any state
    other than their declared attribute, which isn't always the case, and
    can lead to state leak across request.

    Now CurrentAttributes instances are abandoned at the end of a request,
    and a new instance is created at the start of the next request.

    Jean Boussier, Janko Marohnić

  • Add public API for before_fork_hook in parallel testing.

    Introduces a public API for calling the before fork hooks implemented by parallel testing.

    parallelize_before_fork do
        # perform an action before test processes are forked
    end

    Eileen M. Uchitelle

  • Implement ability to skip creating parallel testing databases.

    With parallel testing, Rails will create a database per process. If this isn't
    desirable or you would like to implement databases handling on your own, you can
    now turn off this default behavior.

    To skip creating a database per process, you can change it via the
    parallelize method:

    parallelize(workers: 10, parallelize_databases: false)

    or via the application configuration:

    config.active_support.parallelize_databases = false

    Eileen M. Uchitelle

  • Allow to configure maximum cache key sizes

    When the key exceeds the configured limit (250 bytes by default), it will be truncated and
    the di...

Read more

8.1.0.rc1

15 Oct 00:50
v8.1.0.rc1
4720fe9

Choose a tag to compare

8.1.0.rc1 Pre-release
Pre-release

Active Support

  • Remove deprecated passing a Time object to Time#since.

    Rafael Mendonça França

  • Remove deprecated Benchmark.ms method. It is now defined in the benchmark gem.

    Rafael Mendonça França

  • Remove deprecated addition for Time instances with ActiveSupport::TimeWithZone.

    Rafael Mendonça França

  • Remove deprecated support for to_time to preserve the system local time. It will now always preserve the receiver
    timezone.

    Rafael Mendonça França

  • Deprecate config.active_support.to_time_preserves_timezone.

    Rafael Mendonça França

  • Standardize event name formatting in assert_event_reported error messages.

    The event name in failure messages now uses .inspect (e.g., name: "user.created")
    to match assert_events_reported and provide type clarity between strings and symbols.
    This only affects tests that assert on the failure message format itself.

    George Ma

  • Fix Enumerable#sole to return the full tuple instead of just the first element of the tuple.

    Olivier Bellone

  • Fix parallel tests hanging when worker processes die abruptly.

    Previously, if a worker process was killed (e.g., OOM killed, kill -9) during parallel
    test execution, the test suite would hang forever waiting for the dead worker.

    Joshua Young

  • Add config.active_support.escape_js_separators_in_json.

    Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.

    Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
    As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.

    Étienne Barrié, Jean Boussier

  • Fix NameError when class_attribute is defined on instance singleton classes.

    Previously, calling class_attribute on an instance's singleton class would raise
    a NameError when accessing the attribute through the instance.

    object = MyClass.new
    object.singleton_class.class_attribute :foo, default: "bar"
    object.foo # previously raised NameError, now returns "bar"

    Joshua Young

  • Introduce ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting
    to enable event reporter debug mode in tests.

    The previous way to enable debug mode is by using #with_debug on the
    event reporter itself, which is too verbose. This new helper will help
    clear up any confusion on how to test debug events.

    Gannon McGibbon

  • Add ActiveSupport::StructuredEventSubscriber for consuming notifications and
    emitting structured event logs. Events may be emitted with the #emit_event
    or #emit_debug_event methods.

    class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber
      def notification(event)
        emit_event("my.notification", data: 1)
      end
    end

    Adrianna Chang

  • ActiveSupport::FileUpdateChecker does not depend on Time.now to prevent unecessary reloads with time travel test helpers

    Jan Grodowski

Active Model

  • Add reset_token: { expires_in: ... } option to has_secure_password.

    Allows configuring the expiry duration of password reset tokens (default remains 15 minutes for backwards compatibility).

    has_secure_password reset_token: { expires_in: 1.hour }

    Jevin Sew, Abeid Ahmed

Active Record

  • Add replicas to test database parallelization setup.

    Setup and configuration of databases for parallel testing now includes replicas.

    This fixes an issue when using a replica database, database selector middleware,
    and non-transactional tests, where integration tests running in parallel would select
    the base test database, i.e. db_test, instead of the numbered parallel worker database,
    i.e. db_test_{n}.

    Adam Maas

  • Support virtual (not persisted) generated columns on PostgreSQL 18+

    PostgreSQL 18 introduces virtual (not persisted) generated columns,
    which are now the default unless the stored: true option is explicitly specified on PostgreSQL 18+.

    create_table :users do |t|
      t.string :name
      t.virtual :lower_name,  type: :string,  as: "LOWER(name)", stored: false
      t.virtual :name_length, type: :integer, as: "LENGTH(name)"
    end

    Yasuo Honda

  • Optimize schema dumping to prevent duplicate file generation.

    ActiveRecord::Tasks::DatabaseTasks.dump_all now tracks which schema files
    have already been dumped and skips dumping the same file multiple times.
    This improves performance when multiple database configurations share the
    same schema dump path.

    Mikey Gough, Hartley McGuire

  • Add structured events for Active Record:

    • active_record.strict_loading_violation
    • active_record.sql

    Gannon McGibbon

  • Add support for integer shard keys.

    # Now accepts symbols as shard keys.
    ActiveRecord::Base.connects_to(shards: {
      1: { writing: :primary_shard_one, reading: :primary_shard_one },
      2: { writing: :primary_shard_two, reading: :primary_shard_two},
    })
    
    ActiveRecord::Base.connected_to(shard: 1) do
      # ..
    end

    Nony Dutton

  • Add ActiveRecord::Base.only_columns

    Similar in use case to ignored_columns but listing columns to consider rather than the ones
    to ignore.

    Can be useful when working with a legacy or shared database schema, or to make safe schema change
    in two deploys rather than three.

    Anton Kandratski

  • Use PG::Connection#close_prepared (protocol level Close) to deallocate
    prepared statements when available.

    To enable its use, you must have pg >= 1.6.0, libpq >= 17, and a PostgreSQL
    database version >= 17.

    Hartley McGuire, Andrew Jackson

  • Fix query cache for pinned connections in multi threaded transactional tests

    When a pinned connection is used across separate threads, they now use a separate cache store
    for each thread.

    This improve accuracy of system tests, and any test using multiple threads.

    Heinrich Lee Yu, Jean Boussier

  • Fix time attribute dirty tracking with timezone conversions.

    Time-only attributes now maintain a fixed date of 2000-01-01 during timezone conversions,
    preventing them from being incorrectly marked as changed due to date shifts.

    This fixes an issue where time attributes would be marked as changed when setting the same time value
    due to timezone conversion causing internal date shifts.

    Prateek Choudhary

  • Skip calling PG::Connection#cancel in cancel_any_running_query
    when using libpq >= 18 with pg < 1.6.0, due to incompatibility.
    Rollback still runs, but may take longer.

    Yasuo Honda, Lars Kanis

  • Don't add id_value attribute alias when attribute/column with that name already exists.

    Rob Lewis

Action View

  • The BEGIN template annotation/comment was previously printed on the same line as the following element. We now insert a newline inside the comment so it spans two lines without adding visible whitespace to the HTML output to enhance readability.

    Before:

    <!-- BEGIN /Users/siaw23/Desktop/rails/actionview/test/fixtures/actionpack/test/greeting.html.erb --><p>This is grand!</p>
    

    After:

    <!-- BEGIN /Users/siaw23/Desktop/rails/actionview/test/fixtures/actionpack/test/greeting.html.erb
    --><p>This is grand!</p>
    

    Emmanuel Hayford

  • Add structured events for Action View:

    • action_view.render_template
    • action_view.render_partial
    • action_view.render_layout
    • action_view.render_collection
    • action_view.render_start

    Gannon McGibbon

  • Fix label with for option not getting prefixed by form namespace value

    Abeid Ahmed, Hartley McGuire

  • Add fetchpriority to Link headers to match HTML generated by preload_link_tag.

    Guillermo Iguaran

Action Pack

  • Add link-local IP ranges to ActionDispatch::RemoteIp default proxies.

    Link-local addresses (169.254.0.0/16 for IPv4 and fe80::/10 for IPv6)
    are now included in the default trusted proxy list, similar to private IP ranges.

    Adam Daniels

  • remote_ip will no longer ignore IPs in X-Forwarded-For headers if they
    are accompanied by port information.

    Duncan Brown, Prevenios Marinos, Masafumi Koba, Adam Daniels

  • Add action_dispatch.verbose_redirect_logs setting that logs where redirects were called from.

    Similar to active_record.verbose_query_logs and active_job.verbose_enqueue_logs, this adds a line in your logs that shows where a redirect was called from.

    Example:

    Redirected to http://localhost:3000/posts/1
    ↳ app/controllers/posts_controller.rb:32:in `block (2 levels) in create'
    

    Dennis Paagman

  • Add engine route filtering and better formatting in bin/rails routes.

    Allow engine routes to be filterable in the routing inspector, and
    improve formatting of engine routing output.

    Before:

    > bin/rails routes -e engine_only
    No routes were found for this grep pattern.
    For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html.
    

    After:

    > bin/rails routes -e engine_only
    Routes for application:
    No routes were found for this grep pattern.
    For more information about routes, see the Rails guide: https://guides.rubyonrails.o...
    
Read more

8.0.3

22 Sep 22:19
v8.0.3
529f933

Choose a tag to compare

Active Support

  • ActiveSupport::FileUpdateChecker does not depend on Time.now to prevent unnecessary reloads with time travel test helpers

    Jan Grodowski

  • Fix ActiveSupport::BroadcastLogger from executing a block argument for each logger (tagged, info, etc.).

    Jared Armstrong

  • Make ActiveSupport::Logger #freeze-friendly.

    Joshua Young

  • Fix ActiveSupport::HashWithIndifferentAccess#transform_keys! removing defaults.

    Hartley McGuire

  • Fix ActiveSupport::HashWithIndifferentAccess#tranform_keys! to handle collisions.

    If the transformation would result in a key equal to another not yet transformed one,
    it would result in keys being lost.

    Before:

    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"c" => 1}

    After:

    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"c" => 1, "d" => 2}

    Jason T Johnson, Jean Boussier

  • Fix ActiveSupport::Cache::MemCacheStore#read_multi to handle network errors.

    This method specifically wasn't handling network errors like other codepaths.

    Alessandro Dal Grande

  • Fix configuring RedisCacheStore with raw: true.

    fatkodima

  • Fix Enumerable#sole for infinite collections.

    fatkodima

Active Model

  • Fix has_secure_password to perform confirmation validation of the password even when blank.

    The validation was incorrectly skipped when the password only contained whitespace characters.

    Fabio Sangiovanni

Active Record

  • Fix query cache for pinned connections in multi threaded transactional tests

    When a pinned connection is used across separate threads, they now use a separate cache store
    for each thread.

    This improve accuracy of system tests, and any test using multiple threads.

    Heinrich Lee Yu, Jean Boussier

  • Don't add id_value attribute alias when attribute/column with that name already exists.

    Rob Lewis

  • Fix false positive change detection involving STI and polymorphic has one relationships.

    Polymorphic has_one relationships would always be considered changed when defined in a STI child
    class, causing nedless extra autosaves.

    David Fritsch

  • Skip calling PG::Connection#cancel in cancel_any_running_query
    when using libpq >= 18 with pg < 1.6.0, due to incompatibility.
    Rollback still runs, but may take longer.

    Yasuo Honda, Lars Kanis

  • Fix stale association detection for polymorphic belongs_to.

    Florent Beaurain, Thomas Crambert

  • Fix removal of PostgreSQL version comments in structure.sql for latest PostgreSQL versions which include \restrict

    Brendan Weibrecht

  • Allow setting schema_format in database configuration.

    primary:
      schema_format: ruby
    

    Useful in multi-database setups to have different formats per-database.

    T S Vallender

  • Use ntuples to populate row_count instead of count for Postgres

    Jonathan Calvert

  • Fix #merge with #or or #and and a mixture of attributes and SQL strings resulting in an incorrect query.

    base = Comment.joins(:post).where(user_id: 1).where("recent = 1")
    puts base.merge(base.where(draft: true).or(Post.where(archived: true))).to_sql

    Before:

    SELECT "comments".* FROM "comments"
    INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
    WHERE (recent = 1)
    AND (
      "comments"."user_id" = 1
      AND (recent = 1)
      AND "comments"."draft" = 1
      OR "posts"."archived" = 1
    )

    After:

    SELECT "comments".* FROM "comments"
    INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
    WHERE "comments"."user_id" = 1
    AND (recent = 1)
    AND (
      "comments"."user_id" = 1
      AND (recent = 1)
      AND "comments"."draft" = 1
      OR "posts"."archived" = 1
    )

    Joshua Young

  • Fix inline has_and_belongs_to_many fixtures for tables with composite primary keys.

    fatkodima

  • Fix migration log message for down operations.

    Bernardo Barreto

  • Prepend extra_flags in postgres' structure_load

    When specifying structure_load_flags with a postgres adapter, the flags
    were appended to the default flags, instead of prepended.
    This caused issues with flags not being taken into account by postgres.

    Alice Loeser

  • Fix annotate comments to propagate to update_all/delete_all.

    fatkodima

  • Fix checking whether an unpersisted record is include?d in a strictly
    loaded has_and_belongs_to_many association.

    Hartley McGuire

  • create_or_find_by will now correctly rollback a transaction.

    When using create_or_find_by, raising a ActiveRecord::Rollback error
    in a after_save callback had no effect, the transaction was committed
    and a record created.

    Edouard Chin

  • Gracefully handle Timeout.timeout firing during connection configuration.

    Use of Timeout.timeout could result in improperly initialized database connection.

    This could lead to a partially configured connection being used, resulting in various exceptions,
    the most common being with the PostgreSQLAdapter raising undefined method 'key?' for nil
    or TypeError: wrong argument type nil (expected PG::TypeMap).

    Jean Boussier

  • Fix stale state for composite foreign keys in belongs_to associations.

    Varun Sharma

Action View

  • Fix label with for option not getting prefixed by form namespace value

    Abeid Ahmed, Hartley McGuire

  • Fix javascript_include_tag type option to accept either strings and symbols.

    javascript_include_tag "application", type: :module
    javascript_include_tag "application", type: "module"

    Previously, only the string value was recognized.

    Jean Boussier

  • Fix excerpt helper with non-whitespace separator.

    Jonathan Hefner

Action Pack

  • URL helpers for engines mounted at the application root handle SCRIPT_NAME correctly.

    Fixed an issue where SCRIPT_NAME is not applied to paths generated for routes in an engine
    mounted at "/".

    Mike Dalessio

  • Fix Rails.application.reload_routes! from clearing almost all routes.

    When calling Rails.application.reload_routes! inside a middleware of
    a Rake task, it was possible under certain conditions that all routes would be cleared.
    If ran inside a middleware, this would result in getting a 404 on most page you visit.
    This issue was only happening in development.

    Edouard Chin

  • Address rack 3.2 deprecations warnings.

    warning: Status code :unprocessable_entity is deprecated and will be removed in a future version of Rack.
    Please use :unprocessable_content instead.
    

    Rails API will transparently convert one into the other for the foreseeable future.

    Earlopain, Jean Boussier

  • Support hash-source in Content Security Policy.

    madogiwa

  • Always return empty body for HEAD requests in PublicExceptions and
    DebugExceptions.

    This is required by Rack::Lint (per RFC9110).

    Hartley McGuire

Active Job

  • Include the actual Active Job locale when serializing rather than I18n locale.

    Adrien S

  • Fix retry_job instrumentation when using :test adapter for Active Job.

    fatkodima

Action Mailer

  • No changes.

Action Cable

  • Fixed compatibility with redis gem 5.4.1

    Jean Boussier

  • Fixed a possible race condition in stream_from.

    OuYangJinTing

Active Storage

  • Address deprecation of Aws::S3::Object#upload_stream in ActiveStorage::Service::S3Service.

    Joshua Young

  • Fix config.active_storage.touch_attachment_records to work with eager loading.

    fatkodima

Action Mailbox

  • No changes.

Action Text

  • Add rollup-plugin-terser as a dev dependency.

    Édouard Chin

Railties

  • Fix polymorphic_url and polymorphic_path not working when routes are not loaded.

    Édouard Chin

  • Fix Rails console to not override user defined IRB_NAME.

    Only change the prompt name if it hasn't been customized in .irbrc.

    Jarrett Lusso

Guides

  • No changes.

8.1.0.beta1

04 Sep 12:30
v8.1.0.beta1
80827ca

Choose a tag to compare

8.1.0.beta1 Pre-release
Pre-release

Active Support

  • Add ActiveSupport::Cache::Store#namespace= and #namespace.

    Can be used as an alternative to Store#clear in some situations such as parallel
    testing.

    Nick Schwaderer

  • Create parallel_worker_id helper for running parallel tests. This allows users to
    know which worker they are currently running in.

    Nick Schwaderer

  • Make the cache of ActiveSupport::Cache::Strategy::LocalCache::Middleware updatable.

    If the cache client at Rails.cache of a booted application changes, the corresponding
    mounted middleware needs to update in order for request-local caches to be setup properly.
    Otherwise, redundant cache operations will erroneously hit the datastore.

    Gannon McGibbon

  • Add assert_events_reported test helper for ActiveSupport::EventReporter.

    This new assertion allows testing multiple events in a single block, regardless of order:

    assert_events_reported([
      { name: "user.created", payload: { id: 123 } },
      { name: "email.sent", payload: { to: "[email protected]" } }
    ]) do
      create_user_and_send_welcome_email
    end

    George Ma

  • Add ActiveSupport::TimeZone#standard_name method.

    zone = ActiveSupport::TimeZone['Hawaii']
    # Old way
    ActiveSupport::TimeZone::MAPPING[zone.name]
    # New way
    zone.standard_name # => 'Pacific/Honolulu'

    Bogdan Gusiev

  • Add Structured Event Reporter, accessible via Rails.event.

    The Event Reporter provides a unified interface for producing structured events in Rails
    applications:

    Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")

    It supports adding tags to events:

    Rails.event.tagged("graphql") do
      # Event includes tags: { graphql: true }
      Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")
    end

    As well as context:

    # All events will contain context: {request_id: "abc123", shop_id: 456}
    Rails.event.set_context(request_id: "abc123", shop_id: 456)

    Events are emitted to subscribers. Applications register subscribers to
    control how events are serialized and emitted. Subscribers must implement
    an #emit method, which receives the event hash:

    class LogSubscriber
      def emit(event)
        payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
        source_location = event[:source_location]
        log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
        Rails.logger.info(log)
      end
    end

    Adrianna Chang

  • Make ActiveSupport::Logger #freeze-friendly.

    Joshua Young

  • Make ActiveSupport::Gzip.compress deterministic based on input.

    ActiveSupport::Gzip.compress used to include a timestamp in the output,
    causing consecutive calls with the same input data to have different output
    if called during different seconds. It now always sets the timestamp to 0
    so that the output is identical for any given input.

    Rob Brackett

  • Given an array of Thread::Backtrace::Location objects, the new method
    ActiveSupport::BacktraceCleaner#clean_locations returns an array with the
    clean ones:

    clean_locations = backtrace_cleaner.clean_locations(caller_locations)

    Filters and silencers receive strings as usual. However, the path
    attributes of the locations in the returned array are the original,
    unfiltered ones, since locations are immutable.

    Xavier Noria

  • Improve CurrentAttributes and ExecutionContext state managment in test cases.

    Previously these two global state would be entirely cleared out whenever calling
    into code that is wrapped by the Rails executor, typically Action Controller or
    Active Job helpers:

    test "#index works" do
      CurrentUser.id = 42
      get :index
      CurrentUser.id == nil
    end

    Now re-entering the executor properly save and restore that state.

    Jean Boussier

  • The new method ActiveSupport::BacktraceCleaner#first_clean_location
    returns the first clean location of the caller's call stack, or nil.
    Locations are Thread::Backtrace::Location objects. Useful when you want to
    report the application-level location where something happened as an object.

    Xavier Noria

  • FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.

    Ermolaev Andrey, zzak

  • The new method ActiveSupport::BacktraceCleaner#first_clean_frame returns
    the first clean frame of the caller's backtrace, or nil. Useful when you
    want to report the application-level frame where something happened as a
    string.

    Xavier Noria

  • Always clear CurrentAttributes instances.

    Previously CurrentAttributes instance would be reset at the end of requests.
    Meaning its attributes would be re-initialized.

    This is problematic because it assume these objects don't hold any state
    other than their declared attribute, which isn't always the case, and
    can lead to state leak across request.

    Now CurrentAttributes instances are abandoned at the end of a request,
    and a new instance is created at the start of the next request.

    Jean Boussier, Janko Marohnić

  • Add public API for before_fork_hook in parallel testing.

    Introduces a public API for calling the before fork hooks implemented by parallel testing.

    parallelize_before_fork do
        # perform an action before test processes are forked
    end

    Eileen M. Uchitelle

  • Implement ability to skip creating parallel testing databases.

    With parallel testing, Rails will create a database per process. If this isn't
    desirable or you would like to implement databases handling on your own, you can
    now turn off this default behavior.

    To skip creating a database per process, you can change it via the
    parallelize method:

    parallelize(workers: 10, parallelize_databases: false)

    or via the application configuration:

    config.active_support.parallelize_databases = false

    Eileen M. Uchitelle

  • Allow to configure maximum cache key sizes

    When the key exceeds the configured limit (250 bytes by default), it will be truncated and
    the digest of the rest of the key appended to it.

    Note that previously ActiveSupport::Cache::RedisCacheStore allowed up to 1kb cache keys before
    truncation, which is now reduced to 250 bytes.

    config.cache_store = :redis_cache_store, { max_key_size: 64 }

    fatkodima

  • Use UNLINK command instead of DEL in ActiveSupport::Cache::RedisCacheStore for non-blocking deletion.

    Aron Roh

  • Add Cache#read_counter and Cache#write_counter

    Rails.cache.write_counter("foo", 1)
    Rails.cache.read_counter("foo") # => 1
    Rails.cache.increment("foo")
    Rails.cache.read_counter("foo") # => 2

    Alex Ghiculescu

  • Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports

    Captures all reported errors from within the block that match the given
    error class.

    reports = capture_error_reports(IOError) do
      Rails.error.report(IOError.new("Oops"))
      Rails.error.report(IOError.new("Oh no"))
      Rails.error.report(StandardError.new)
    end
    
    assert_equal 2, reports.size
    assert_equal "Oops", reports.first.error.message
    assert_equal "Oh no", reports.last.error.message

    Andrew Novoselac

  • Introduce ActiveSupport::ErrorReporter#add_middleware

    When reporting an error, the error context middleware will be called with the reported error
    and base execution context. The stack may mutate the context hash. The mutated context will
    then be passed to error subscribers. Middleware receives the same parameters as ErrorReporter#report.

    Andrew Novoselac, Sam Schmidt

  • Change execution wrapping to report all exceptions, including Exception.

    If a more serious error like SystemStackError or NoMemoryError happens,
    the error reporter should be able to report these kinds of exceptions.

    Gannon McGibbon

  • ActiveSupport::Testing::Parallelization.before_fork_hook allows declaration of callbacks that
    are invoked immediately before forking test workers.

    Mike Dalessio

  • Allow the #freeze_time testing helper to accept a date or time argument.

    Time.current # => Sun, 09 Jul 2024 15:34:49 EST -05:00
    freeze_time Time.current + 1.day
    sleep 1
    Time.current # => Mon, 10 Jul 2024 15:34:49 EST -05:00

    Joshua Young

  • ActiveSupport::JSON now accepts options

    It is now possible to pass options to ActiveSupport::JSON:

    ActiveSupport::JSON.decode('{"key": "value"}', symbolize_names: true) # => { key: "value" }

    matthaigh27

  • ActiveSupport::Testing::NotificationAssertions's assert_notification now matches against payload subsets by default.

    Previously the following assertion would fail due to excess key vals in the notification payload. Now with payload subset matching, it will pass.

    assert_notification("post.submitted", title: "Cool Post") do
      ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: "Cool Body")
    end

    Additionally, you can now persist a matched notification for more customized ass...

Read more