A summary of data about the Ruby ecosystem.

Recent Releases of https://github.com/rails/rails

https://github.com/rails/rails - 8.1.1

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.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 8.0.4

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.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 7.2.3

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).

    Jean Boussier

  • The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".

    Mike Dalessio

  • Handle libpq returning a database version of 0 on no/bad connection in PostgreSQLAdapter.

    Before, this version would be cached and an error would be raised during connection configuration when
    comparing it with the minimum required version for the adapter. This meant that the connection could
    never be successfully configured on subsequent reconnection attempts.

    Now, this is treated as a connection failure consistent with libpq, raising a ActiveRecord::ConnectionFailed
    and ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.

    Joshua Young, Rian McGuire

  • 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 nil or TypeError: wrong argument type nil (expected PG::TypeMap)`.

    Jean Boussier

  • Fix a case where a non-retryable query could be marked retryable.

    Hartley McGuire

  • Handle circular references when autosaving associations.

    zzak

  • Prevent persisting invalid record.

    Edouard Chin

  • Fix support for PostgreSQL enum types with commas in their name.

    Arthur Hess

  • Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.

    Nikita Vasilevsky

  • Fix joining on a scoped association with string joins and bind parameters.

    class Instructor < ActiveRecord::Base
      has_many :instructor_roles, -> { active }
    end
    
    class InstructorRole < ActiveRecord::Base
      scope :active, -> {
        joins("JOIN students ON instructor_roles.student_id = students.id")
        .where(students { status: 1 })
      }
    end
    
    Instructor.joins(:instructor_roles).first
    

    The above example would result in ActiveRecord::StatementInvalid because the
    active scope bind parameters would be lost.

    Jean Boussier

  • Fix a potential race condition with system tests and transactional fixtures.

    Sjoerd Lagarde

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

    Ryuta Kamizono

  • Fix sum with qualified name on loaded relation.

    Chris Gunther

  • Fix autosave associations to no longer validated unmodified associated records.

    Active Record was incorrectly performing validation on associated record that
    weren't created nor modified as part of the transaction:

    Post.create!(author: User.find(1)) # Fail if user is invalid
    

    Jean Boussier

  • Remember when a database connection has recently been verified (for
    two seconds, by default), to avoid repeated reverifications during a
    single request.

    This should recreate a similar rate of verification as in Rails 7.1,
    where connections are leased for the duration of a request, and thus
    only verified once.

    Matthew Draper

  • 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

  • Fix MySQL default functions getting dropped when changing a column's nullability.

    Bastian Bartmann

  • Fix add_unique_constraint/add_check_constraint//add_foreign_key` to be revertible when
    given invalid options.

    fatkodima

  • Fix asynchronous destroying of polymorphic belongs_to associations.

    fatkodima

  • NOT VALID constraints should not dump in create_table.

    Ryuta Kamizono

  • Fix finding by nil composite primary key association.

    fatkodima

  • Fix parsing of SQLite foreign key names when they contain non-ASCII characters

    Zacharias Knudsen

  • Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines.

    Steve Hill

  • Ensure normalized attribute queries use IS NULL consistently for nil and normalized nil values.

    Joshua Young

  • Restore back the ability to pass only database name for DATABASE_URL.

    fatkodima

  • Fix order with using association name as an alias.

    Ryuta Kamizono

  • Improve invalid argument error for with.

    Ryuta Kamizono

  • Deduplicate with CTE expressions.

    fatkodima

Action View

  • 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 recoginized.

    Jean Boussier

  • Fix excerpt helper with non-whitespace separator.

    Jonathan Hefner

  • Respect html_options[:form] when collection_checkboxes generates the
    hidden <input>.

    Riccardo Odone

  • Layouts have access to local variables passed to render.

    This fixes #31680 which was a regression in Rails 5.1.

    Mike Dalessio

  • Argument errors related to strict locals in templates now raise an
    ActionView::StrictLocalsError, and all other argument errors are reraised as-is.

    Previously, any ArgumentError raised during template rendering was swallowed during strict
    local error handling, so that an ArgumentError unrelated to strict locals (e.g., a helper
    method invoked with incorrect arguments) would be replaced by a similar ArgumentError with an
    unrelated backtrace, making it difficult to debug templates.

    Now, any ArgumentError unrelated to strict locals is reraised, preserving the original
    backtrace for developers.

    Also note that ActionView::StrictLocalsError is a subclass of ArgumentError, so any existing
    code that rescues ArgumentError will continue to work.

    Fixes #52227.

    Mike Dalessio

  • Fix stack overflow error in dependency tracker when dealing with circular dependencies

    Jean Boussier

  • Fix a crash in ERB template error highlighting when the error occurs on a
    line in the compiled template that is past the end of the source template.

    Martin Emde

  • Improve reliability of ERB template error highlighting.
    Fix infinite loops and crashes in highlighting and
    improve tolerance for alternate ERB handlers.

    Martin Emde

Action Pack

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

    Sean Doyle

  • 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 forseable future.

    Earlopain, Jean Boussier

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

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

    Hartley McGuire

  • Fix url_for to handle :path_params gracefully when it's not a Hash.

    Prevents various security scanners from causing exceptions.

    Martin Emde

  • Fix ActionDispatch::Executor to unwrap exceptions like other error reporting middlewares.

    Jean Boussier

  • Fix NoMethodError when a non-string CSRF token is passed through headers.

    Ryan Heneise

  • Fix invalid response when rescuing ActionController::Redirecting::UnsafeRedirectError in a controller.

    Alex Ghiculescu

Active Job

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

    Adrien S

  • Avoid crashing in Active Job logger when logging enqueueing errors

    ActiveJob.perform_all_later could fail with a TypeError when all
    provided jobs failed to be enqueueed.

    Efstathios Stivaros

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

  • Ensure the Postgresql adapter always use a dedicated connection even during system tests.

    Fix an issue with the Action Cable Postgresql adapter causing deadlock or various weird
    pg client error during system tests.

    Jean Boussier

Active Storage

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

    fatkodima

  • A Blob will no longer autosave associated Attachment.

    This fixes an issue where a record with an attachment would have
    its dirty attributes reset, preventing your after commit callbacks
    on that record to behave as expected.

    Note that this change doesn't require any changes on your application
    and is supposed to be internal. Active Storage Attachment will continue
    to be autosaved (through a different relation).

    Edouard-chin

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Use secret_key_base from ENV or credentials when present locally.

    When ENV["SECRET_KEY_BASE"] or
    Rails.application.credentials.secret_key_base is set for test or
    development, it is used for the Rails.config.secret_key_base,
    instead of generating a tmp/local_secret.txt file.

    Petrik de Heus

Guides

  • No changes.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 7.1.6

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 nil or TypeError: 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 nil or TypeError: 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.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 7.0.10

See https://github.com/rails/rails/releases/tag/v7.0.9 for information about this release.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 7.0.9

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.

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 8.1.0

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: "user@example.com" } }
    ]) 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: "user@example.com")
    

    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: "user@example.com")
    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 assertions.

    notification = assert_notification("post.submitted", title: "Cool Post") do
      ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: Body.new("Cool Body"))
    end
    
    assert_instance_of(Body, notification.payload[:body])
    

    Nicholas La Roux

  • Deprecate String#mb_chars and ActiveSupport::Multibyte::Chars.

    These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
    aware. There is no legitimate reasons to need these APIs today.

    Jean Boussier

  • Deprecate ActiveSupport::Configurable

    Sean Doyle

  • nil.to_query("key") now returns key.

    Previously it would return key=, preventing round tripping with Rack::Utils.parse_nested_query.

    Erol Fornoles

  • Avoid wrapping redis in a ConnectionPool when using ActiveSupport::Cache::RedisCacheStore if the :redis
    option is already a ConnectionPool.

    Joshua Young

  • Alter ERB::Util.tokenize to return :PLAIN token with full input string when string doesn't contain ERB tags.

    Martin Emde

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

    Martin Emde

  • Add ActiveSupport::Testing::NotificationAssertions module to help with testing ActiveSupport::Notifications.

    Nicholas La Roux, Yishu See, Sean Doyle

  • ActiveSupport::CurrentAttributes#attributes now will return a new hash object on each call.

    Previously, the same hash object was returned each time that method was called.

    fatkodima

  • ActiveSupport::JSON.encode supports CIDR notation.

    Previously:

    ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0\""
    

    After this change:

    ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0/24\""
    

    Taketo Takashima

  • Make ActiveSupport::FileUpdateChecker faster when checking many file-extensions.

    Jonathan del Strother

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

  • Add except_on: option for validation callbacks.

    Ben Sheldon

  • Backport ActiveRecord::Normalization to ActiveModel::Attributes::Normalization

    class User
      include ActiveModel::Attributes
      include ActiveModel::Attributes::Normalization
    
      attribute :email, :string
    
      normalizes :email, with: -> email { email.strip.downcase }
    end
    
    user = User.new
    user.email =    " CRUISE-CONTROL@EXAMPLE.COM\n"
    user.email # => "cruise-control@example.com"
    

    Sean Doyle

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 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

  • Remove deprecated :unsigned_float and :unsigned_decimal column methods for MySQL.

    Rafael Mendonça França

  • Remove deprecated :retries option for the SQLite3 adapter.

    Rafael Mendonça França

  • Introduce new database configuration options keepalive, max_age, and
    min_connections -- and rename pool to max_connections to match.

    There are no changes to default behavior, but these allow for more specific
    control over pool behavior.

    Matthew Draper, Chris AtLee, Rachael Wright-Munn

  • Move LIMIT validation from query generation to when limit() is called.

    Hartley McGuire, Shuyang

  • Add ActiveRecord::CheckViolation error class for check constraint violations.

    Ryuta Kamizono

  • Add ActiveRecord::ExclusionViolation error class for exclusion constraint violations.

    When an exclusion constraint is violated in PostgreSQL, the error will now be raised
    as ActiveRecord::ExclusionViolation instead of the generic ActiveRecord::StatementInvalid,
    making it easier to handle these specific constraint violations in application code.

    This follows the same pattern as other constraint violation error classes like
    RecordNotUnique for unique constraint violations and InvalidForeignKey for
    foreign key constraint violations.

    Ryuta Kamizono

  • Attributes filtered by filter_attributes will now also be filtered by filter_parameters
    so sensitive information is not leaked.

    Jill Klang

  • Add connection.current_transaction.isolation API to check current transaction's isolation level.

    Returns the isolation level if it was explicitly set via the isolation: parameter
    or through ActiveRecord.with_transaction_isolation_level, otherwise returns nil.
    Nested transactions return the parent transaction's isolation level.

    # Returns nil when no transaction
    User.connection.current_transaction.isolation # => nil
    
    # Returns explicitly set isolation level
    User.transaction(isolation: :serializable) do
      User.connection.current_transaction.isolation # => :serializable
    end
    
    # Returns nil when isolation not explicitly set
    User.transaction do
      User.connection.current_transaction.isolation # => nil
    end
    
    # Nested transactions inherit parent's isolation
    User.transaction(isolation: :read_committed) do
      User.transaction do
        User.connection.current_transaction.isolation # => :read_committed
      end
    end
    

    Kir Shatrov

  • 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

  • Make schema dumper to account for ActiveRecord.dump_schemas when dumping in :ruby format.

    fatkodima

  • Add :touch option to update_column/update_columns methods.

    # Will update :updated_at/:updated_on alongside :nice column.
    user.update_column(:nice, true, touch: true)
    
    # Will update :updated_at/:updated_on alongside :last_ip column
    user.update_columns(last_ip: request.remote_ip, touch: true)
    

    Dmitrii Ivliev

  • Optimize Active Record batching further when using ranges.

    Tested on a PostgreSQL table with 10M records and batches of 10k records, the generation
    of relations for the 1000 batches was 4.8x faster (6.8s vs. 1.4s), used 900x
    less bandwidth (180MB vs. 0.2MB) and allocated 45x less memory (490MB vs. 11MB).

    Maxime Réty, fatkodima

  • Include current character length in error messages for index and table name length validations.

    Joshua Young

  • Add rename_schema method for PostgreSQL.

    T S Vallender

  • Implement support for deprecating associations:

    has_many :posts, deprecated: true
    

    With that, Active Record will report any usage of the posts association.

    Three reporting modes are supported (:warn, :raise, and :notify), and
    backtraces can be enabled or disabled. Defaults are :warn mode and
    disabled backtraces.

    Please, check the docs for further details.

    Xavier Noria

  • PostgreSQL adapter create DB now supports locale_provider and locale.

    Bengt-Ove Hollaender

  • Use ntuples to populate row_count instead of count for Postgres

    Jonathan Calvert

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

    Hartley McGuire

  • Add ability to change transaction isolation for all pools within a block.

    This functionality is useful if your application needs to change the database
    transaction isolation for a request or action.

    Calling ActiveRecord.with_transaction_isolation_level(level) {} in an around filter or
    middleware will set the transaction isolation for all pools accessed within the block,
    but not for the pools that aren't.

    This works with explicit and implicit transactions:

    ActiveRecord.with_transaction_isolation_level(:read_committed) do
      Tag.transaction do # opens a transaction explicitly
        Tag.create!
      end
    end
    
    ActiveRecord.with_transaction_isolation_level(:read_committed) do
      Tag.create! # opens a transaction implicitly
    end
    

    Eileen M. Uchitelle

  • Raise ActiveRecord::MissingRequiredOrderError when order dependent finder methods (e.g. #first, #last) are
    called without order values on the relation, and the model does not have any order columns (implicit_order_column,
    query_constraints, or primary_key) to fall back on.

    This change will be introduced with a new framework default for Rails 8.1, and the current behavior of not raising
    an error has been deprecated with the aim of removing the configuration option in Rails 8.2.

    config.active_record.raise_on_missing_required_finder_order_columns = true
    

    Joshua Young

  • :class_name is now invalid in polymorphic belongs_to associations.

    Reason is :class_name does not make sense in those associations because
    the class name of target records is dynamic and stored in the type column.

    Existing polymorphic associations setting this option can just delete it.
    While it did not raise, it had no effect anyway.

    Xavier Noria

  • Add support for multiple databases to db:migrate:reset.

    Joé Dupuis

  • Add affected_rows to ActiveRecord::Result.

    Jenny Shen

  • Enable passing retryable SqlLiterals to #where.

    Hartley McGuire

  • Set default for primary keys in insert_all/upsert_all.

    Previously in Postgres, updating and inserting new records in one upsert wasn't possible
    due to null primary key values. nil primary key values passed into insert_all/upsert_all
    are now implicitly set to the default insert value specified by adapter.

    Jenny Shen

  • Add a load hook active_record_database_configurations for ActiveRecord::DatabaseConfigurations

    Mike Dalessio

  • Use TRUE and FALSE for SQLite queries with boolean columns.

    Hartley McGuire

  • Bump minimum supported SQLite to 3.23.0.

    Hartley McGuire

  • Allow allocated Active Records to lookup associations.

    Previously, the association cache isn't setup on allocated record objects, so association
    lookups will crash. Test frameworks like mocha use allocate to check for stubbable instance
    methods, which can trigger an association lookup.

    Gannon McGibbon

  • Encryption now supports support_unencrypted_data: true being set per-attribute.

    Previously this only worked if ActiveRecord::Encryption.config.support_unencrypted_data == true.
    Now, if the global config is turned off, you can still opt in for a specific attribute.

    # ActiveRecord::Encryption.config.support_unencrypted_data = true
    class User < ActiveRecord::Base
      encrypts :name, support_unencrypted_data: false # only supports encrypted data
      encrypts :email # supports encrypted or unencrypted data
    end
    
    # ActiveRecord::Encryption.config.support_unencrypted_data = false
    class User < ActiveRecord::Base
      encrypts :name, support_unencrypted_data: true # supports encrypted or unencrypted data
      encrypts :email  # only supports encrypted data
    end
    

    Alex Ghiculescu

  • Model generator no longer needs a database connection to validate column types.

    Mike Dalessio

  • Allow signed ID verifiers to be configurable via Rails.application.message_verifiers

    Prior to this change, the primary way to configure signed ID verifiers was
    to set signed_id_verifier on each model class:

    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Comment.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    

    And if the developer did not set signed_id_verifier, a verifier would be
    instantiated with a secret derived from secret_key_base and the following
    options:

    { digest: "SHA256", serializer: JSON, url_safe: true }
    

    Thus it was cumbersome to rotate configuration for all verifiers.

    This change defines a new Rails config: config.active_record.use_legacy_signed_id_verifier.
    The default value is :generate_and_verify, which preserves the previous
    behavior. However, when set to :verify, signed ID verifiers will use
    configuration from Rails.application.message_verifiers (specifically,
    Rails.application.message_verifiers["active_record/signed_id"]) to
    generate and verify signed IDs, but will also verify signed IDs using the
    older configuration.

    To avoid complication, the new behavior only applies when signed_id_verifier_secret
    is not set on a model class or any of its ancestors. Additionally,
    signed_id_verifier_secret is now deprecated. If you are currently setting
    signed_id_verifier_secret on a model class, you can set signed_id_verifier
    instead:

    # BEFORE
    Post.signed_id_verifier_secret = "my secret"
    
    # AFTER
    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
    

    To ease migration, signed_id_verifier has also been changed to behave as a
    class_attribute (i.e. inheritable), but only when signed_id_verifier_secret
    is not set
    :

    # BEFORE
    ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    
    # AFTER
    ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
    
    Post.signed_id_verifier_secret = "my secret" # => deprecation warning
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    

    Note, however, that it is recommended to eventually migrate from
    model-specific verifiers to a unified configuration managed by
    Rails.application.message_verifiers. ActiveSupport::MessageVerifier#rotate
    can facilitate that transition. For example:

    # BEFORE
    # Generate and verify signed Post IDs using Post-specific configuration
    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("post secret", ...)
    
    # AFTER
    # Generate and verify signed Post IDs using the unified configuration
    Post.signed_id_verifier = Post.signed_id_verifier.dup
    # Fall back to Post-specific configuration when verifying signed IDs
    Post.signed_id_verifier.rotate("post secret", ...)
    

    Ali Sepehri, Jonathan Hefner

  • 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

  • Allow bypassing primary key/constraint addition in implicit_order_column

    When specifying multiple columns in an array for implicit_order_column, adding
    nil as the last element will prevent appending the primary key to order
    conditions. This allows more precise control of indexes used by
    generated queries. It should be noted that this feature does introduce the risk
    of API misbehavior if the specified columns are not fully unique.

    Issy Long

  • Allow setting the schema_format via database configuration.

    primary:
      schema_format: ruby
    

    Useful for multi-database setups when apps require different formats per-database.

    T S Vallender

  • Support disabling indexes for MySQL v8.0.0+ and MariaDB v10.6.0+

    MySQL 8.0.0 added an option to disable indexes from being used by the query
    optimizer by making them "invisible". This allows the index to still be maintained
    and updated but no queries will be permitted to use it. This can be useful for adding
    new invisible indexes or making existing indexes invisible before dropping them
    to ensure queries are not negatively affected.
    See https://dev.mysql.com/blog-archive/mysql-8-0-invisible-indexes/ for more details.

    MariaDB 10.6.0 also added support for this feature by allowing indexes to be "ignored"
    in queries. See https://mariadb.com/kb/en/ignored-indexes/ for more details.

    Active Record now supports this option for MySQL 8.0.0+ and MariaDB 10.6.0+ for
    index creation and alteration where the new index option enabled: true/false can be
    passed to column and index methods as below:

    add_index :users, :email, enabled: false
    enable_index :users, :email
    add_column :users, :dob, :string, index: { enabled: false }
    
    change_table :users do |t|
      t.index :name, enabled: false
      t.index :dob
      t.disable_index :dob
      t.column :username, :string, index: { enabled: false }
      t.references :account, index: { enabled: false }
    end
    
    create_table :users do |t|
      t.string :name, index: { enabled: false }
      t.string :email
      t.index :email, enabled: false
    end
    

    Merve Taner

  • Respect implicit_order_column in ActiveRecord::Relation#reverse_order.

    Joshua Young

  • Add column types to ActiveRecord::Result for SQLite3.

    Andrew Kane

  • Raise ActiveRecord::ReadOnlyError when pessimistically locking with a readonly role.

    Joshua Young

  • Fix using the SQLite3Adapter's dbconsole method outside of a Rails application.

    Hartley McGuire

  • Fix migrating multiple databases with ActiveRecord::PendingMigration action.

    Gannon McGibbon

  • Enable automatically retrying idempotent association queries on connection
    errors.

    Hartley McGuire

  • Add allow_retry to sql.active_record instrumentation.

    This enables identifying queries which queries are automatically retryable on connection errors.

    Hartley McGuire

  • Better support UPDATE with JOIN for Postgresql and SQLite3

    Previously when generating update queries with one or more JOIN clauses,
    Active Record would use a sub query which would prevent to reference the joined
    tables in the SET clause, for instance:

    Comment.joins(:post).update_all("title = posts.title")
    

    This is now supported as long as the relation doesn't also use a LIMIT, ORDER or
    GROUP BY clause. This was supported by the MySQL adapter for a long time.

    Jean Boussier

  • Introduce a before-fork hook in ActiveSupport::Testing::Parallelization to clear existing
    connections, to avoid fork-safety issues with the mysql2 adapter.

    Fixes #41776

    Mike Dalessio, Donal McBreen

  • PoolConfig no longer keeps a reference to the connection class.

    Keeping a reference to the class caused subtle issues when combined with reloading in
    development. Fixes #54343.

    Mike Dalessio

  • Fix SQL notifications sometimes not sent when using async queries.

    Post.async_count
    ActiveSupport::Notifications.subscribed(->(*) { "Will never reach here" }) do
      Post.count
    end
    

    In rare circumstances and under the right race condition, Active Support notifications
    would no longer be dispatched after using an asynchronous query.
    This is now fixed.

    Edouard Chin

  • Eliminate queries loading dumped schema cache on Postgres

    Improve resiliency by avoiding needing to open a database connection to load the
    type map while defining attribute methods at boot when a schema cache file is
    configured on PostgreSQL databases.

    James Coleman

  • ActiveRecord::Coder::JSON can be instantiated

    Options can now be passed to ActiveRecord::Coder::JSON when instantiating the coder. This allows:

    serialize :config, coder: ActiveRecord::Coder::JSON.new(symbolize_names: true)
    

    matthaigh27

  • Deprecate using insert_all/upsert_all with unpersisted records in associations.

    Using these methods on associations containing unpersisted records will now
    show a deprecation warning, as the unpersisted records will be lost after
    the operation.

    Nick Schwaderer

  • Make column name optional for index_exists?.

    This aligns well with remove_index signature as well, where
    index name doesn't need to be derived from the column names.

    Ali Ismayiliov

  • Change the payload name of sql.active_record notification for eager
    loading from "SQL" to "#{model.name} Eager Load".

    zzak

  • Enable automatically retrying idempotent #exists? queries on connection
    errors.

    Hartley McGuire, classidied

  • Deprecate usage of unsupported methods in conjunction with update_all:

    update_all will now print a deprecation message if a query includes either WITH,
    WITH RECURSIVE or DISTINCT statements. Those were never supported and were ignored
    when generating the SQL query.

    An error will be raised in a future Rails release. This behavior will be consistent
    with delete_all which currently raises an error for unsupported statements.

    Edouard Chin

  • The table columns inside schema.rb are now sorted alphabetically.

    Previously they'd be sorted by creation order, which can cause merge conflicts when two
    branches modify the same table concurrently.

    John Duff

  • Introduce versions formatter for the schema dumper.

    It is now possible to override how schema dumper formats versions information inside the
    structure.sql file. Currently, the versions are simply sorted in the decreasing order.
    Within large teams, this can potentially cause many merge conflicts near the top of the list.

    Now, the custom formatter can be provided with a custom sorting logic (e.g. by hash values
    of the versions), which can greatly reduce the number of conflicts.

    fatkodima

  • Serialized attributes can now be marked as comparable.

    A not rare issue when working with serialized attributes is that the serialized representation of an object
    can change over time. Either because you are migrating from one serializer to the other (e.g. YAML to JSON or to msgpack),
    or because the serializer used subtly changed its output.

    One example is libyaml that used to have some extra trailing whitespaces, and recently fixed that.
    When this sorts of thing happen, you end up with lots of records that report being changed even though
    they aren't, which in the best case leads to a lot more writes to the database and in the worst case lead to nasty bugs.

    The solution is to instead compare the deserialized representation of the object, however Active Record
    can't assume the deserialized object has a working == method. Hence why this new functionality is opt-in.

    serialize :config, type: Hash, coder: JSON, comparable: true
    

    Jean Boussier

  • Fix MySQL default functions getting dropped when changing a column's nullability.

    Bastian Bartmann

  • SQLite extensions can be configured in config/database.yml.

    The database configuration option extensions: allows an application to load SQLite extensions
    when using sqlite3 >= v2.4.0. The array members may be filesystem paths or the names of
    modules that respond to .to_path:

    development:
      adapter: sqlite3
      extensions:
        - SQLean::UUID                     # module name responding to `.to_path`
        - .sqlpkg/nalgeon/crypto/crypto.so # or a filesystem path
        - <%= AppExtensions.location %>    # or ruby code returning a path
    

    Mike Dalessio

  • ActiveRecord::Middleware::ShardSelector supports granular database connection switching.

    A new configuration option, class_name:, is introduced to
    config.active_record.shard_selector to allow an application to specify the abstract connection
    class to be switched by the shard selection middleware. The default class is
    ActiveRecord::Base.

    For example, this configuration tells ShardSelector to switch shards using
    AnimalsRecord.connected_to:

    config.active_record.shard_selector = { class_name: "AnimalsRecord" }
    

    Mike Dalessio

  • Reset relations after insert_all/upsert_all.

    Bulk insert/upsert methods will now call reset if used on a relation, matching the behavior of update_all.

    Milo Winningham

  • Use _N as a parallel tests databases suffixes

    Peviously, -N was used as a suffix. This can cause problems for RDBMSes
    which do not support dashes in database names.

    fatkodima

  • Remember when a database connection has recently been verified (for
    two seconds, by default), to avoid repeated reverifications during a
    single request.

    This should recreate a similar rate of verification as in Rails 7.1,
    where connections are leased for the duration of a request, and thus
    only verified once.

    Matthew Draper

  • Allow to reset cache counters for multiple records.

    Aircraft.reset_counters([1, 2, 3], :wheels_count)
    

    It produces much fewer queries compared to the custom implementation using looping over ids.
    Previously: O(ids.size * counters.size) queries, now: O(ids.size + counters.size) queries.

    fatkodima

  • Add affected_rows to sql.active_record Notification.

    Hartley McGuire

  • Fix sum when performing a grouped calculation.

    User.group(:friendly).sum no longer worked. This is fixed.

    Edouard Chin

  • Add support for enabling or disabling transactional tests per database.

    A test class can now override the default use_transactional_tests setting
    for individual databases, which can be useful if some databases need their
    current state to be accessible to an external process while tests are running.

    class MostlyTransactionalTest < ActiveSupport::TestCase
      self.use_transactional_tests = true
      skip_transactional_tests_for_database :shared
    end
    

    Matthew Cheetham, Morgan Mareve

  • Cast query_cache value when using URL configuration.

    zzak

  • NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.

    Ryuta Kamizono

  • PG::UnableToSend: no connection to the server is now retryable as a connection-related exception

    Kazuma Watanabe

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

  • Add CSP nonce to Link headers generated by preload_link_tag.

    Alexander Gitter

  • Allow current_page? to match against specific HTTP method(s) with a method: option.

    Ben Sheldon

  • Remove autocomplete="off" on hidden inputs generated by the following
    tags:

    • form_tag, token_tag, method_tag

    As well as the hidden parameter fields included in button_to,
    check_box, select (with multiple) and file_field forms.

    nkulway

  • Enable configuring the strategy for tracking dependencies between Action
    View templates.

    The existing :regex strategy is kept as the default, but with
    load_defaults 8.1 the strategy will be :ruby (using a real Ruby parser).

    Hartley McGuire

  • Introduce relative_time_in_words helper

    relative_time_in_words(3.minutes.from_now) # => "in 3 minutes"
    relative_time_in_words(3.minutes.ago) # => "3 minutes ago"
    relative_time_in_words(10.seconds.ago, include_seconds: true) # => "less than 10 seconds ago"
    

    Matheus Richard

  • Make nonce: false remove the nonce attribute from javascript_tag, javascript_include_tag, and stylesheet_link_tag.

    francktrouillez

  • Add dom_target helper to create dom_id-like strings from an unlimited
    number of objects.

    Ben Sheldon

  • Respect html_options[:form] when collection_checkboxes generates the
    hidden <input>.

    Riccardo Odone

  • Layouts have access to local variables passed to render.

    This fixes #31680 which was a regression in Rails 5.1.

    Mike Dalessio

  • Argument errors related to strict locals in templates now raise an
    ActionView::StrictLocalsError, and all other argument errors are reraised as-is.

    Previously, any ArgumentError raised during template rendering was swallowed during strict
    local error handling, so that an ArgumentError unrelated to strict locals (e.g., a helper
    method invoked with incorrect arguments) would be replaced by a similar ArgumentError with an
    unrelated backtrace, making it difficult to debug templates.

    Now, any ArgumentError unrelated to strict locals is reraised, preserving the original
    backtrace for developers.

    Also note that ActionView::StrictLocalsError is a subclass of ArgumentError, so any existing
    code that rescues ArgumentError will continue to work.

    Fixes #52227.

    Mike Dalessio

  • Improve error highlighting of multi-line methods in ERB templates or
    templates where the error occurs within a do-end block.

    Martin Emde

  • Fix a crash in ERB template error highlighting when the error occurs on a
    line in the compiled template that is past the end of the source template.

    Martin Emde

  • Improve reliability of ERB template error highlighting.
    Fix infinite loops and crashes in highlighting and
    improve tolerance for alternate ERB handlers.

    Martin Emde

  • Allow hidden_field and hidden_field_tag to accept a custom autocomplete value.

    brendon

  • Add a new configuration content_security_policy_nonce_auto for automatically adding a nonce to the tags affected by the directives specified by the content_security_policy_nonce_directives configuration option.

    francktrouillez

Action Pack

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

    Sean Doyle

  • 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.org/routing.html.
    
    Routes for Test::Engine:
    Prefix Verb URI Pattern       Controller#Action
    engine GET  /engine_only(.:format) a#b
    

    Dennis Paagman, Gannon McGibbon

  • Add structured events for Action Pack and Action Dispatch:

    • action_dispatch.redirect
    • action_controller.request_started
    • action_controller.request_completed
    • action_controller.callback_halted
    • action_controller.rescue_from_handled
    • action_controller.file_sent
    • action_controller.redirected
    • action_controller.data_sent
    • action_controller.unpermitted_parameters
    • action_controller.fragment_cache

    Adrianna Chang

  • 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

  • Update ActionController::Metal::RateLimiting to support passing method names to :by and :with

    class SignupsController < ApplicationController
      rate_limit to: 10, within: 1.minute, with: :redirect_with_flash
    
      private
        def redirect_with_flash
          redirect_to root_url, alert: "Too many requests!"
        end
    end
    

    Sean Doyle

  • Optimize ActionDispatch::Http::URL.build_host_url when protocol is included in host.

    When using URL helpers with a host that includes the protocol (e.g., { host: "https://example.com" }),
    skip unnecessary protocol normalization and string duplication since the extracted protocol is already
    in the correct format. This eliminates 2 string allocations per URL generation and provides a ~10%
    performance improvement for this case.

    Joshua Young, Hartley McGuire

  • Allow action_controller.logger to be disabled by setting it to nil or false instead of always defaulting to Rails.logger.

    Roberto Miranda

  • Remove deprecated support to a route to multiple paths.

    Rafael Mendonça França

  • Remove deprecated support for using semicolons as a query string separator.

    Before:

    ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
    # => [["foo", "bar"], ["baz", "quux"]]
    

    After:

    ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
    # => [["foo", "bar;baz=quux"]]
    

    Rafael Mendonça França

  • Remove deprecated support to skipping over leading brackets in parameter names in the parameter parser.

    Before:

    ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" }
    ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }
    

    After:

    ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" }
    ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } }
    

    Rafael Mendonça França

  • Deprecate Rails.application.config.action_dispatch.ignore_leading_brackets.

    Rafael Mendonça França

  • Raise ActionController::TooManyRequests error from ActionController::RateLimiting

    Requests that exceed the rate limit raise an ActionController::TooManyRequests error.
    By default, Action Dispatch rescues the error and responds with a 429 Too Many Requests status.

    Sean Doyle

  • Add .md/.markdown as Markdown extensions and add a default markdown: renderer:

    class Page
      def to_markdown
        body
      end
    end
    
    class PagesController < ActionController::Base
      def show
        @page = Page.find(params[:id])
    
        respond_to do |format|
          format.html
          format.md { render markdown: @page }
        end
      end
    end
    

    DHH

  • Add headers to engine routes inspection command

    Petrik de Heus

  • Add "Copy as text" button to error pages

    Mikkel Malmberg

  • Add scope: option to rate_limit method.

    Previously, it was not possible to share a rate limit count between several controllers, since the count was by
    default separate for each controller.

    Now, the scope: option solves this problem.

    class APIController < ActionController::API
      rate_limit to: 2, within: 2.seconds, scope: "api"
    end
    
    class API::PostsController < APIController
      # ...
    end
    
    class API::UsersController < APIController
      # ...
    end
    

    ArthurPV, Kamil Hanus

  • Add support for rack.response_finished callbacks in ActionDispatch::Executor.

    The executor middleware now supports deferring completion callbacks to later
    in the request lifecycle by utilizing Rack's rack.response_finished mechanism,
    when available. This enables applications to define rack.response_finished callbacks
    that may rely on state that would be cleaned up by the executor's completion callbacks.

    Adrianna Chang, Hartley McGuire

  • Produce a log when rescue_from is invoked.

    Steven Webb, Jean Boussier

  • Allow hosts redirects from hosts Rails configuration

    config.action_controller.allowed_redirect_hosts << "example.com"
    

    Kevin Robatel

  • rate_limit.action_controller notification has additional payload

    additional values: count, to, within, by, name, cache_key

    Jonathan Rochkind

  • Add JSON support to the built-in health controller.

    The health controller now responds to JSON requests with a structured response
    containing status and timestamp information. This makes it easier for monitoring
    tools and load balancers to consume health check data programmatically.

    # /up.json
    {
      "status": "up",
      "timestamp": "2025-09-19T12:00:00Z"
    }
    

    Francesco Loreti, Juan Vásquez

  • Allow to open source file with a crash from the browser.

    Igor Kasyanchuk

  • Always check query string keys for valid encoding just like values are checked.

    Casper Smits

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

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

    Hartley McGuire

  • Add comprehensive support for HTTP Cache-Control request directives according to RFC 9111.

    Provides a request.cache_control_directives object that gives access to request cache directives:

    # Boolean directives
    request.cache_control_directives.only_if_cached?  # => true/false
    request.cache_control_directives.no_cache?        # => true/false
    request.cache_control_directives.no_store?        # => true/false
    request.cache_control_directives.no_transform?    # => true/false
    
    # Value directives
    request.cache_control_directives.max_age          # => integer or nil
    request.cache_control_directives.max_stale        # => integer or nil (or true for valueless max-stale)
    request.cache_control_directives.min_fresh        # => integer or nil
    request.cache_control_directives.stale_if_error   # => integer or nil
    
    # Special helpers for max-stale
    request.cache_control_directives.max_stale?         # => true if max-stale present (with or without value)
    request.cache_control_directives.max_stale_unlimited? # => true only for valueless max-stale
    

    Example usage:

    def show
      if request.cache_control_directives.only_if_cached?
        @article = Article.find_cached(params[:id])
        return head(:gateway_timeout) if @article.nil?
      else
        @article = Article.find(params[:id])
      end
    
      render :show
    end
    

    egg528

  • Add assert_in_body/assert_not_in_body as the simplest way to check if a piece of text is in the response body.

    DHH

  • Include cookie name when calculating maximum allowed size.

    Hartley McGuire

  • Implement must-understand directive according to RFC 9111.

    The must-understand directive indicates that a cache must understand the semantics of the response status code, or discard the response. This directive is enforced to be used only with no-store to ensure proper cache behavior.

    class ArticlesController < ApplicationController
      def show
        @article = Article.find(params[:id])
    
        if @article.special_format?
          must_understand
          render status: 203 # Non-Authoritative Information
        else
          fresh_when @article
        end
      end
    end
    

    heka1024

  • The JSON renderer doesn't escape HTML entities or Unicode line separators anymore.

    Using render json: will no longer escape <, >, &, U+2028 and U+2029 characters that can cause errors
    when the resulting JSON is embedded in JavaScript, or vulnerabilities when the resulting JSON is embedded in HTML.

    Since the renderer is used to return a JSON document as application/json, it's typically not necessary to escape
    those characters, and it improves performance.

    Escaping will still occur when the :callback option is set, since the JSON is used as JavaScript code in this
    situation (JSONP).

    You can use the :escape option or set config.action_controller.escape_json_responses to true to restore the
    escaping behavior.

    class PostsController < ApplicationController
      def index
        render json: Post.last(30), escape: true
      end
    end
    

    Étienne Barrié, Jean Boussier

  • Load lazy route sets before inserting test routes

    Without loading lazy route sets early, we miss after_routes_loaded callbacks, or risk
    invoking them with the test routes instead of the real ones if another load is triggered by an engine.

    Gannon McGibbon

  • Raise AbstractController::DoubleRenderError if head is called after rendering.

    After this change, invoking head will lead to an error if response body is already set:

    class PostController < ApplicationController
      def index
        render locals: {}
        head :ok
      end
    end
    

    Iaroslav Kurbatov

  • The Cookie Serializer can now serialize an Active Support SafeBuffer when using message pack.

    Such code would previously produce an error if an application was using messagepack as its cookie serializer.

    class PostController < ApplicationController
      def index
        flash.notice = t(:hello_html) # This would try to serialize a SafeBuffer, which was not possible.
      end
    end
    

    Edouard Chin

  • 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

  • Add resource name to the ArgumentError that's raised when invalid :only or :except options are given to #resource or #resources

    This makes it easier to locate the source of the problem, especially for routes drawn by gems.

    Before:

    :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    After:

    Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    Jeremy Green

  • A route pointing to a non-existing controller now returns a 500 instead of a 404.

    A controller not existing isn't a routing error that should result
    in a 404, but a programming error that should result in a 500 and
    be reported.

    Until recently, this was hard to untangle because of the support
    for dynamic :controller segment in routes, but since this is
    deprecated and will be removed in Rails 8.1, we can now easily
    not consider missing controllers as routing errors.

    Jean Boussier

  • Add check_collisions option to ActionDispatch::Session::CacheStore.

    Newly generated session ids use 128 bits of randomness, which is more than
    enough to ensure collisions can't happen, but if you need to harden sessions
    even more, you can enable this option to check in the session store that the id
    is indeed free you can enable that option. This however incurs an extra write
    on session creation.

    Shia

  • In ExceptionWrapper, match backtrace lines with built templates more often,
    allowing improved highlighting of errors within do-end blocks in templates.
    Fix for Ruby 3.4 to match new method labels in backtrace.

    Martin Emde

  • Allow setting content type with a symbol of the Mime type.

    # Before
    response.content_type = "text/html"
    
    # After
    response.content_type = :html
    

    Petrik de Heus

Active Job

  • Add structured events for Active Job:

    • active_job.enqueued
    • active_job.bulk_enqueued
    • active_job.started
    • active_job.completed
    • active_job.retry_scheduled
    • active_job.retry_stopped
    • active_job.discarded
    • active_job.interrupt
    • active_job.resume
    • active_job.step_skipped
    • active_job.step_started
    • active_job.step

    Adrianna Chang

  • Deprecate built-in sidekiq adapter.

    If you're using this adapter, upgrade to sidekiq 7.3.3 or later to use the sidekiq gem's adapter.

    fatkodima

  • Remove deprecated internal SuckerPunch adapter in favor of the adapter included with the sucker_punch gem.

    Rafael Mendonça França

  • Remove support to set ActiveJob::Base.enqueue_after_transaction_commit to :never, :always and :default.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.active_job.enqueue_after_transaction_commit.

    Rafael Mendonça França

  • ActiveJob::Serializers::ObjectSerializers#klass method is now public.

    Custom Active Job serializers must have a public #klass method too.
    The returned class will be index allowing for faster serialization.

    Jean Boussier

  • Allow jobs to the interrupted and resumed with Continuations

    A job can use Continuations by including the ActiveJob::Continuable
    concern. Continuations split jobs into steps. When the queuing system
    is shutting down jobs can be interrupted and their progress saved.

    class ProcessImportJob
      include ActiveJob::Continuable
    
      def perform(import_id)
        @import = Import.find(import_id)
    
        # block format
        step :initialize do
          @import.initialize
        end
    
        # step with cursor, the cursor is saved when the job is interrupted
        step :process do |step|
          @import.records.find_each(start: step.cursor) do |record|
            record.process
            step.advance! from: record.id
          end
        end
    
        # method format
        step :finalize
    
        private
          def finalize
            @import.finalize
          end
      end
    end
    

    Donal McBreen

  • Defer invocation of ActiveJob enqueue callbacks until after commit when
    enqueue_after_transaction_commit is enabled.

    Will Roever

  • Add report: option to ActiveJob::Base#retry_on and #discard_on

    When the report: option is passed, errors will be reported to the error reporter
    before being retried / discarded.

    Andrew Novoselac

  • Accept a block for ActiveJob::ConfiguredJob#perform_later.

    This was inconsistent with a regular ActiveJob::Base#perform_later.

    fatkodima

  • Raise a more specific error during deserialization when a previously serialized job class is now unknown.

    ActiveJob::UnknownJobClassError will be raised instead of a more generic
    NameError to make it easily possible for adapters to tell if the NameError
    was raised during job execution or deserialization.

    Earlopain

Action Mailer

  • Add structured events for Action Mailer:

    • action_mailer.delivered
    • action_mailer.processed

    Gannon McGibbon

  • Add deliver_all_later to enqueue multiple emails at once.

    user_emails = User.all.map { |user| Notifier.welcome(user) }
    ActionMailer.deliver_all_later(user_emails)
    
    # use a custom queue
    ActionMailer.deliver_all_later(user_emails, queue: :my_queue)
    

    This can greatly reduce the number of round-trips to the queue datastore.
    For queue adapters that do not implement the enqueue_all method, we
    fall back to enqueuing email jobs indvidually.

    fatkodima

Action Cable

  • Allow passing composite channels to ActionCable::Channel#stream_for – e.g. stream_for [ group, group.owner ]

    hey-leon

  • Allow setting nil as subscription connection identifier for Redis.

    Nguyen Nguyen

Active Storage

  • Add structured events for Active Storage:

    • active_storage.service_upload
    • active_storage.service_download
    • active_storage.service_streaming_download
    • active_storage.preview
    • active_storage.service_delete
    • active_storage.service_delete_prefixed
    • active_storage.service_exist
    • active_storage.service_url
    • active_storage.service_mirror

    Gannon McGibbon

  • Allow analyzers and variant transformer to be fully configurable

    # ActiveStorage.analyzers can be set to an empty array:
    config.active_storage.analyzers = []
    # => ActiveStorage.analyzers = []
    
    # or use custom analyzer:
    config.active_storage.analyzers = [ CustomAnalyzer ]
    # => ActiveStorage.analyzers = [ CustomAnalyzer ]
    

    If no configuration is provided, it will use the default analyzers.

    You can also disable variant processor to remove warnings on startup about missing gems.

    config.active_storage.variant_processor = :disabled
    

    zzak, Alexandre Ruban

  • Remove deprecated :azure storage service.

    Rafael Mendonça França

  • Remove unnecessary calls to the GCP metadata server.

    Calling Google::Auth.get_application_default triggers an explicit call to
    the metadata server - given it was being called for significant number of
    file operations, it can lead to considerable tail latencies and even metadata
    server overloads. Instead, it's preferable (and significantly more efficient)
    that applications use:

    Google::Apis::RequestOptions.default.authorization = Google::Auth.get_application_default(...)
    

    In the cases applications do not set that, the GCP libraries automatically determine credentials.

    This also enables using credentials other than those of the associated GCP
    service account like when using impersonation.

    Alex Coomans

  • Direct upload progress accounts for server processing time.

    Jeremy Daer

  • Delegate ActiveStorage::Filename#to_str to #to_s

    Supports checking String equality:

    filename = ActiveStorage::Filename.new("file.txt")
    filename == "file.txt" # => true
    filename in "file.txt" # => true
    "file.txt" == filename # => true
    

    Sean Doyle

  • A Blob will no longer autosave associated Attachment.

    This fixes an issue where a record with an attachment would have
    its dirty attributes reset, preventing your after commit callbacks
    on that record to behave as expected.

    Note that this change doesn't require any changes on your application
    and is supposed to be internal. Active Storage Attachment will continue
    to be autosaved (through a different relation).

    Edouard-chin

Action Mailbox

  • Add reply_to_address extension method on Mail::Message.

    Mr0grog

Action Text

  • De-couple @rails/actiontext/attachment_upload.js from Trix.Attachment

    Implement @rails/actiontext/index.js with a direct-upload:progress event
    listeners and Promise resolution.

    Sean Doyle

  • Capture block content for form helper methods

    <%= rich_textarea_tag :content, nil do %>
      <h1>hello world</h1>
    <% end %>
    <!-- <input type="hidden" name="content" id="trix_input_1" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    
    <%= rich_textarea :message, :content, input: "trix_input_1" do %>
      <h1>hello world</h1>
    <% end %>
    <!-- <input type="hidden" name="message[content]" id="trix_input_1" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    
    <%= form_with model: Message.new do |form| %>
      <%= form.rich_textarea :content do %>
        <h1>hello world</h1>
      <% end %>
    <% end %>
    <!-- <form action="/messages" accept-charset="UTF-8" method="post"><input type="hidden" name="message[content]" id="message_content_trix_input_message" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    

    Sean Doyle

  • Generalize :rich_text_area Capybara selector

    Prepare for more Action Text-capable WYSIWYG editors by making
    :rich_text_area rely on the presence of [role="textbox"] and
    [contenteditable] HTML attributes rather than a <trix-editor> element.

    Sean Doyle

  • Forward fill_in_rich_text_area options to Capybara

    fill_in_rich_textarea "Rich text editor", id: "trix_editor_1", with: "Hello world!"
    

    Sean Doyle

  • Attachment upload progress accounts for server processing time.

    Jeremy Daer

  • The Trix dependency is now satisfied by a gem, action_text-trix, rather than vendored
    files. This allows applications to bump Trix versions independently of Rails
    releases. Effectively this also upgrades Trix to >= 2.1.15.

    Mike Dalessio

  • Change ActionText::RichText#embeds assignment from before_save to before_validation

    Sean Doyle

Railties

  • Suggest bin/rails action_text:install from Action Dispatch error page

    Sean Doyle

  • Remove deprecated STATS_DIRECTORIES.

    Rafael Mendonça França

  • Remove deprecated bin/rake stats command.

    Rafael Mendonça França

  • Remove deprecated rails/console/methods.rb file.

    Rafael Mendonça França

  • Don't generate system tests by default.

    Rails scaffold generator will no longer generate system tests by default. To enable this pass --system-tests=true or generate them with bin/rails generate system_test name_of_test.

    Eileen M. Uchitelle

  • Optionally skip bundler-audit.

    Skips adding the bin/bundler-audit & config/bundler-audit.yml if the gem is not installed when bin/rails app:update runs.

    Passes an option to --skip-bundler-audit when new apps are generated & adds that same option to the --minimal generator flag.

    Jill Klang

  • Show engine routes in /rails/info/routes as well.

    Petrik de Heus

  • Exclude asset_path configuration from Kamal deploy.yml for API applications.

    API applications don't serve assets, so the asset_path configuration in deploy.yml
    is not needed and can cause 404 errors on in-flight requests. The asset_path is now
    only included for regular Rails applications that serve assets.

    Saiqul Haq

  • Reverted the incorrect default config.public_file_server.headers config.

    If you created a new application using Rails 8.1.0.beta1, make sure to regenerate
    config/environments/production.rb, or to manually edit the config.public_file_server.headers
    configuration to just be:

    # Cache assets for far-future expiry since they are all digest stamped.
    config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
    

    Jean Boussier

  • Add command rails credentials:fetch PATH to get the value of a credential from the credentials file.

    $ bin/rails credentials:fetch kamal_registry.password
    

    Matthew Nguyen, Jean Boussier

  • Generate static BCrypt password digests in fixtures instead of dynamic ERB expressions.

    Previously, fixtures with password digest attributes used <%= BCrypt::Password.create("secret") %>,
    which regenerated the hash on each test run. Now generates a static hash with a comment
    showing how to recreate it.

    Nate Smith, Cassia Scheffer

  • Broaden the .gitignore entry when adding a credentials key to ignore all key files.

    Greg Molnar

  • Remove unnecessary ruby-version input from ruby/setup-ruby

    TangRufus

  • Add --reset option to bin/setup which will call db:reset as part of the setup.

    DHH

  • Add RuboCop cache restoration to RuboCop job in GitHub Actions workflow templates.

    Lovro Bikić

  • Skip generating mailer-related files in authentication generator if the application does
    not use ActionMailer

    Rami Massoud

  • Introduce bin/ci for running your tests, style checks, and security audits locally or in the cloud.

    The specific steps are defined by a new DSL in config/ci.rb.

    ActiveSupport::ContinuousIntegration.run do
      step "Setup", "bin/setup --skip-server"
      step "Style: Ruby", "bin/rubocop"
      step "Security: Gem audit", "bin/bundler-audit"
      step "Tests: Rails", "bin/rails test test:system"
    end
    

    Optionally use gh-signoff to
    set a green PR status - ready for merge.

    Jeremy Daer, DHH

  • Generate session controller tests when running the authentication generator.

    Jerome Dalbert

  • Add bin/bundler-audit and config/bundler-audit.yml for discovering and managing known security problems with app gems.

    DHH

  • Rails no longer generates a bin/bundle binstub when creating new applications.

    The bin/bundle binstub used to help activate the right version of bundler.
    This is no longer necessary as this mechanism is now part of Rubygem itself.

    Edouard Chin

  • Add a SessionTestHelper module with sign_in_as(user) and sign_out test helpers when
    running rails g authentication. Simplifies authentication in integration tests.

    Bijan Rahnema

  • Rate limit password resets in authentication generator

    This helps mitigate abuse from attackers spamming the password reset form.

    Chris Oliver

  • Update rails new --minimal option

    Extend the --minimal flag to exclude recently added features:
    skip_brakeman, skip_ci, skip_docker, skip_kamal, skip_rubocop, skip_solid and skip_thruster.

    eelcoj

  • Add application-name metadata to application layout

    The following metatag will be added to app/views/layouts/application.html.erb

    <meta name="application-name" content="Name of Rails Application">
    

    Steve Polito

  • Use secret_key_base from ENV or credentials when present locally.

    When ENV["SECRET_KEY_BASE"] or
    Rails.application.credentials.secret_key_base is set for test or
    development, it is used for the Rails.config.secret_key_base,
    instead of generating a tmp/local_secret.txt file.

    Petrik de Heus

  • Introduce RAILS_MASTER_KEY placeholder in generated ci.yml files

    Steve Polito

  • Colorize the Rails console prompt even on non standard environments.

    Lorenzo Zabot

  • Don't enable YJIT in development and test environments

    Development and test environments tend to reload code and redefine methods (e.g. mocking),
    hence YJIT isn't generally faster in these environments.

    Ali Ismayilov, Jean Boussier

  • Only include PermissionsPolicy::Middleware if policy is configured.

    Petrik de Heus

Guides

  • In the Active Job bug report template set the queue adapter to the
    test adapter so that assert_enqueued_with can pass.

    Andrew White

  • Ensure all bug report templates set config.secret_key_base to avoid
    generation of tmp/local_secret.txt files when running the report template.

    Andrew White

- Ruby
Published by rafaelfranca 4 months ago

https://github.com/rails/rails - 8.1.0.rc1

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.org/routing.html.
    
    Routes for Test::Engine:
    Prefix Verb URI Pattern       Controller#Action
    engine GET  /engine_only(.:format) a#b
    

    Dennis Paagman, Gannon McGibbon

  • Add structured events for Action Pack and Action Dispatch:

    • action_dispatch.redirect
    • action_controller.request_started
    • action_controller.request_completed
    • action_controller.callback_halted
    • action_controller.rescue_from_handled
    • action_controller.file_sent
    • action_controller.redirected
    • action_controller.data_sent
    • action_controller.unpermitted_parameters
    • action_controller.fragment_cache

    Adrianna Chang

  • 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

  • Update ActionController::Metal::RateLimiting to support passing method names to :by and :with

    class SignupsController < ApplicationController
      rate_limit to: 10, within: 1.minute, with: :redirect_with_flash
    
      private
        def redirect_with_flash
          redirect_to root_url, alert: "Too many requests!"
        end
    end
    

    Sean Doyle

  • Optimize ActionDispatch::Http::URL.build_host_url when protocol is included in host.

    When using URL helpers with a host that includes the protocol (e.g., { host: "https://example.com" }),
    skip unnecessary protocol normalization and string duplication since the extracted protocol is already
    in the correct format. This eliminates 2 string allocations per URL generation and provides a ~10%
    performance improvement for this case.

    Joshua Young, Hartley McGuire

  • Allow action_controller.logger to be disabled by setting it to nil or false instead of always defaulting to Rails.logger.

    Roberto Miranda

Active Job

  • Add structured events for Active Job:

    • active_job.enqueued
    • active_job.bulk_enqueued
    • active_job.started
    • active_job.completed
    • active_job.retry_scheduled
    • active_job.retry_stopped
    • active_job.discarded
    • active_job.interrupt
    • active_job.resume
    • active_job.step_skipped
    • active_job.step_started
    • active_job.step

    Adrianna Chang

Action Mailer

  • Add structured events for Action Mailer:

    • action_mailer.delivered
    • action_mailer.processed

    Gannon McGibbon

Action Cable

  • No changes.

Active Storage

  • Add structured events for Active Storage:

    • active_storage.service_upload
    • active_storage.service_download
    • active_storage.service_streaming_download
    • active_storage.preview
    • active_storage.service_delete
    • active_storage.service_delete_prefixed
    • active_storage.service_exist
    • active_storage.service_url
    • active_storage.service_mirror

    Gannon McGibbon

  • Allow analyzers and variant transformer to be fully configurable

    # ActiveStorage.analyzers can be set to an empty array:
    config.active_storage.analyzers = []
    # => ActiveStorage.analyzers = []
    
    # or use custom analyzer:
    config.active_storage.analyzers = [ CustomAnalyzer ]
    # => ActiveStorage.analyzers = [ CustomAnalyzer ]
    

    If no configuration is provided, it will use the default analyzers.

    You can also disable variant processor to remove warnings on startup about missing gems.

    config.active_storage.variant_processor = :disabled
    

    zzak, Alexandre Ruban

Action Mailbox

  • No changes.

Action Text

  • De-couple @rails/actiontext/attachment_upload.js from Trix.Attachment

    Implement @rails/actiontext/index.js with a direct-upload:progress event
    listeners and Promise resolution.

    Sean Doyle

  • Capture block content for form helper methods

    <%= rich_textarea_tag :content, nil do %>
      <h1>hello world</h1>
    <% end %>
    <!-- <input type="hidden" name="content" id="trix_input_1" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    
    <%= rich_textarea :message, :content, input: "trix_input_1" do %>
      <h1>hello world</h1>
    <% end %>
    <!-- <input type="hidden" name="message[content]" id="trix_input_1" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    
    <%= form_with model: Message.new do |form| %>
      <%= form.rich_textarea :content do %>
        <h1>hello world</h1>
      <% end %>
    <% end %>
    <!-- <form action="/messages" accept-charset="UTF-8" method="post"><input type="hidden" name="message[content]" id="message_content_trix_input_message" value="&lt;h1&gt;hello world&lt;/h1&gt;"/><trix-editor … -->
    

    Sean Doyle

  • Generalize :rich_text_area Capybara selector

    Prepare for more Action Text-capable WYSIWYG editors by making
    :rich_text_area rely on the presence of [role="textbox"] and
    [contenteditable] HTML attributes rather than a <trix-editor> element.

    Sean Doyle

Railties

  • Suggest bin/rails action_text:install from Action Dispatch error page

    Sean Doyle

  • Remove deprecated STATS_DIRECTORIES.

    Rafael Mendonça França

  • Remove deprecated bin/rake stats command.

    Rafael Mendonça França

  • Remove deprecated rails/console/methods.rb file.

    Rafael Mendonça França

  • Don't generate system tests by default.

    Rails scaffold generator will no longer generate system tests by default. To enable this pass --system-tests=true or generate them with bin/rails generate system_test name_of_test.

    Eileen M. Uchitelle

  • Optionally skip bundler-audit.

    Skips adding the bin/bundler-audit & config/bundler-audit.yml if the gem is not installed when bin/rails app:update runs.

    Passes an option to --skip-bundler-audit when new apps are generated & adds that same option to the --minimal generator flag.

    Jill Klang

  • Show engine routes in /rails/info/routes as well.

    Petrik de Heus

  • Exclude asset_path configuration from Kamal deploy.yml for API applications.

    API applications don't serve assets, so the asset_path configuration in deploy.yml
    is not needed and can cause 404 errors on in-flight requests. The asset_path is now
    only included for regular Rails applications that serve assets.

    Saiqul Haq

  • Reverted the incorrect default config.public_file_server.headers config.

    If you created a new application using Rails 8.1.0.beta1, make sure to regenerate
    config/environments/production.rb, or to manually edit the config.public_file_server.headers
    configuration to just be:

    # Cache assets for far-future expiry since they are all digest stamped.
    config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
    

    Jean Boussier

Guides

  • No changes.

- Ruby
Published by rafaelfranca 5 months ago

https://github.com/rails/rails - 8.0.3

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.

- Ruby
Published by rafaelfranca 5 months ago

https://github.com/rails/rails - 8.1.0.beta1

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: "user@example.com" } }
    ]) 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: "user@example.com")
    

    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: "user@example.com")
    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 assertions.

    notification = assert_notification("post.submitted", title: "Cool Post") do
      ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: Body.new("Cool Body"))
    end
    
    assert_instance_of(Body, notification.payload[:body])
    

    Nicholas La Roux

  • Deprecate String#mb_chars and ActiveSupport::Multibyte::Chars.

    These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
    aware. There is no legitimate reasons to need these APIs today.

    Jean Boussier

  • Deprecate ActiveSupport::Configurable

    Sean Doyle

  • nil.to_query("key") now returns key.

    Previously it would return key=, preventing round tripping with Rack::Utils.parse_nested_query.

    Erol Fornoles

  • Avoid wrapping redis in a ConnectionPool when using ActiveSupport::Cache::RedisCacheStore if the :redis
    option is already a ConnectionPool.

    Joshua Young

  • Alter ERB::Util.tokenize to return :PLAIN token with full input string when string doesn't contain ERB tags.

    Martin Emde

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

    Martin Emde

  • Add ActiveSupport::Testing::NotificationAssertions module to help with testing ActiveSupport::Notifications.

    Nicholas La Roux, Yishu See, Sean Doyle

  • ActiveSupport::CurrentAttributes#attributes now will return a new hash object on each call.

    Previously, the same hash object was returned each time that method was called.

    fatkodima

  • ActiveSupport::JSON.encode supports CIDR notation.

    Previously:

    ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0\""
    

    After this change:

    ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0/24\""
    

    Taketo Takashima

  • Make ActiveSupport::FileUpdateChecker faster when checking many file-extensions.

    Jonathan del Strother

Active Model

  • Add except_on: option for validation callbacks.

    Ben Sheldon

  • Backport ActiveRecord::Normalization to ActiveModel::Attributes::Normalization

    class User
      include ActiveModel::Attributes
      include ActiveModel::Attributes::Normalization
    
      attribute :email, :string
    
      normalizes :email, with: -> email { email.strip.downcase }
    end
    
    user = User.new
    user.email =    " CRUISE-CONTROL@EXAMPLE.COM\n"
    user.email # => "cruise-control@example.com"
    

    Sean Doyle

Active Record

  • Remove deprecated :unsigned_float and :unsigned_decimal column methods for MySQL.

    Rafael Mendonça França

  • Remove deprecated :retries option for the SQLite3 adapter.

    Rafael Mendonça França

  • Introduce new database configuration options keepalive, max_age, and
    min_connections -- and rename pool to max_connections to match.

    There are no changes to default behavior, but these allow for more specific
    control over pool behavior.

    Matthew Draper, Chris AtLee, Rachael Wright-Munn

  • Move LIMIT validation from query generation to when limit() is called.

    Hartley McGuire, Shuyang

  • Add ActiveRecord::CheckViolation error class for check constraint violations.

    Ryuta Kamizono

  • Add ActiveRecord::ExclusionViolation error class for exclusion constraint violations.

    When an exclusion constraint is violated in PostgreSQL, the error will now be raised
    as ActiveRecord::ExclusionViolation instead of the generic ActiveRecord::StatementInvalid,
    making it easier to handle these specific constraint violations in application code.

    This follows the same pattern as other constraint violation error classes like
    RecordNotUnique for unique constraint violations and InvalidForeignKey for
    foreign key constraint violations.

    Ryuta Kamizono

  • Attributes filtered by filter_attributes will now also be filtered by filter_parameters
    so sensitive information is not leaked.

    Jill Klang

  • Add connection.current_transaction.isolation API to check current transaction's isolation level.

    Returns the isolation level if it was explicitly set via the isolation: parameter
    or through ActiveRecord.with_transaction_isolation_level, otherwise returns nil.
    Nested transactions return the parent transaction's isolation level.

    # Returns nil when no transaction
    User.connection.current_transaction.isolation # => nil
    
    # Returns explicitly set isolation level
    User.transaction(isolation: :serializable) do
      User.connection.current_transaction.isolation # => :serializable
    end
    
    # Returns nil when isolation not explicitly set
    User.transaction do
      User.connection.current_transaction.isolation # => nil
    end
    
    # Nested transactions inherit parent's isolation
    User.transaction(isolation: :read_committed) do
      User.transaction do
        User.connection.current_transaction.isolation # => :read_committed
      end
    end
    

    Kir Shatrov

  • Emit a warning for pg gem < 1.6.0 when using PostgreSQL 18+

    Yasuo Honda

  • 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

  • Make schema dumper to account for ActiveRecord.dump_schemas when dumping in :ruby format.

    fatkodima

  • Add :touch option to update_column/update_columns methods.

    # Will update :updated_at/:updated_on alongside :nice column.
    user.update_column(:nice, true, touch: true)
    
    # Will update :updated_at/:updated_on alongside :last_ip column
    user.update_columns(last_ip: request.remote_ip, touch: true)
    

    Dmitrii Ivliev

  • Optimize Active Record batching further when using ranges.

    Tested on a PostgreSQL table with 10M records and batches of 10k records, the generation
    of relations for the 1000 batches was 4.8x faster (6.8s vs. 1.4s), used 900x
    less bandwidth (180MB vs. 0.2MB) and allocated 45x less memory (490MB vs. 11MB).

    Maxime Réty, fatkodima

  • Include current character length in error messages for index and table name length validations.

    Joshua Young

  • Add rename_schema method for PostgreSQL.

    T S Vallender

  • Implement support for deprecating associations:

    has_many :posts, deprecated: true
    

    With that, Active Record will report any usage of the posts association.

    Three reporting modes are supported (:warn, :raise, and :notify), and
    backtraces can be enabled or disabled. Defaults are :warn mode and
    disabled backtraces.

    Please, check the docs for further details.

    Xavier Noria

  • PostgreSQL adapter create DB now supports locale_provider and locale.

    Bengt-Ove Hollaender

  • Use ntuples to populate row_count instead of count for Postgres

    Jonathan Calvert

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

    Hartley McGuire

  • Add ability to change transaction isolation for all pools within a block.

    This functionality is useful if your application needs to change the database
    transaction isolation for a request or action.

    Calling ActiveRecord.with_transaction_isolation_level(level) {} in an around filter or
    middleware will set the transaction isolation for all pools accessed within the block,
    but not for the pools that aren't.

    This works with explicit and implicit transactions:

    ActiveRecord.with_transaction_isolation_level(:read_committed) do
      Tag.transaction do # opens a transaction explicitly
        Tag.create!
      end
    end
    
    ActiveRecord.with_transaction_isolation_level(:read_committed) do
      Tag.create! # opens a transaction implicitly
    end
    

    Eileen M. Uchitelle

  • Raise ActiveRecord::MissingRequiredOrderError when order dependent finder methods (e.g. #first, #last) are
    called without order values on the relation, and the model does not have any order columns (implicit_order_column,
    query_constraints, or primary_key) to fall back on.

    This change will be introduced with a new framework default for Rails 8.1, and the current behavior of not raising
    an error has been deprecated with the aim of removing the configuration option in Rails 8.2.

    config.active_record.raise_on_missing_required_finder_order_columns = true
    

    Joshua Young

  • :class_name is now invalid in polymorphic belongs_to associations.

    Reason is :class_name does not make sense in those associations because
    the class name of target records is dynamic and stored in the type column.

    Existing polymorphic associations setting this option can just delete it.
    While it did not raise, it had no effect anyway.

    Xavier Noria

  • Add support for multiple databases to db:migrate:reset.

    Joé Dupuis

  • Add affected_rows to ActiveRecord::Result.

    Jenny Shen

  • Enable passing retryable SqlLiterals to #where.

    Hartley McGuire

  • Set default for primary keys in insert_all/upsert_all.

    Previously in Postgres, updating and inserting new records in one upsert wasn't possible
    due to null primary key values. nil primary key values passed into insert_all/upsert_all
    are now implicitly set to the default insert value specified by adapter.

    Jenny Shen

  • Add a load hook active_record_database_configurations for ActiveRecord::DatabaseConfigurations

    Mike Dalessio

  • Use TRUE and FALSE for SQLite queries with boolean columns.

    Hartley McGuire

  • Bump minimum supported SQLite to 3.23.0.

    Hartley McGuire

  • Allow allocated Active Records to lookup associations.

    Previously, the association cache isn't setup on allocated record objects, so association
    lookups will crash. Test frameworks like mocha use allocate to check for stubbable instance
    methods, which can trigger an association lookup.

    Gannon McGibbon

  • Encryption now supports support_unencrypted_data: true being set per-attribute.

    Previously this only worked if ActiveRecord::Encryption.config.support_unencrypted_data == true.
    Now, if the global config is turned off, you can still opt in for a specific attribute.

    # ActiveRecord::Encryption.config.support_unencrypted_data = true
    class User < ActiveRecord::Base
      encrypts :name, support_unencrypted_data: false # only supports encrypted data
      encrypts :email # supports encrypted or unencrypted data
    end
    
    # ActiveRecord::Encryption.config.support_unencrypted_data = false
    class User < ActiveRecord::Base
      encrypts :name, support_unencrypted_data: true # supports encrypted or unencrypted data
      encrypts :email  # only supports encrypted data
    end
    

    Alex Ghiculescu

  • Model generator no longer needs a database connection to validate column types.

    Mike Dalessio

  • Allow signed ID verifiers to be configurable via Rails.application.message_verifiers

    Prior to this change, the primary way to configure signed ID verifiers was
    to set signed_id_verifier on each model class:

    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Comment.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    

    And if the developer did not set signed_id_verifier, a verifier would be
    instantiated with a secret derived from secret_key_base and the following
    options:

    { digest: "SHA256", serializer: JSON, url_safe: true }
    

    Thus it was cumbersome to rotate configuration for all verifiers.

    This change defines a new Rails config: config.active_record.use_legacy_signed_id_verifier.
    The default value is :generate_and_verify, which preserves the previous
    behavior. However, when set to :verify, signed ID verifiers will use
    configuration from Rails.application.message_verifiers (specifically,
    Rails.application.message_verifiers["active_record/signed_id"]) to
    generate and verify signed IDs, but will also verify signed IDs using the
    older configuration.

    To avoid complication, the new behavior only applies when signed_id_verifier_secret
    is not set on a model class or any of its ancestors. Additionally,
    signed_id_verifier_secret is now deprecated. If you are currently setting
    signed_id_verifier_secret on a model class, you can set signed_id_verifier
    instead:

    # BEFORE
    Post.signed_id_verifier_secret = "my secret"
    
    # AFTER
    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
    

    To ease migration, signed_id_verifier has also been changed to behave as a
    class_attribute (i.e. inheritable), but only when signed_id_verifier_secret
    is not set
    :

    # BEFORE
    ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    
    # AFTER
    ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
    
    Post.signed_id_verifier_secret = "my secret" # => deprecation warning
    Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    

    Note, however, that it is recommended to eventually migrate from
    model-specific verifiers to a unified configuration managed by
    Rails.application.message_verifiers. ActiveSupport::MessageVerifier#rotate
    can facilitate that transition. For example:

    # BEFORE
    # Generate and verify signed Post IDs using Post-specific configuration
    Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("post secret", ...)
    
    # AFTER
    # Generate and verify signed Post IDs using the unified configuration
    Post.signed_id_verifier = Post.signed_id_verifier.dup
    # Fall back to Post-specific configuration when verifying signed IDs
    Post.signed_id_verifier.rotate("post secret", ...)
    

    Ali Sepehri, Jonathan Hefner

  • 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

  • Allow bypassing primary key/constraint addition in implicit_order_column

    When specifying multiple columns in an array for implicit_order_column, adding
    nil as the last element will prevent appending the primary key to order
    conditions. This allows more precise control of indexes used by
    generated queries. It should be noted that this feature does introduce the risk
    of API misbehavior if the specified columns are not fully unique.

    Issy Long

  • Allow setting the schema_format via database configuration.

    primary:
      schema_format: ruby
    

    Useful for multi-database setups when apps require different formats per-database.

    T S Vallender

  • Support disabling indexes for MySQL v8.0.0+ and MariaDB v10.6.0+

    MySQL 8.0.0 added an option to disable indexes from being used by the query
    optimizer by making them "invisible". This allows the index to still be maintained
    and updated but no queries will be permitted to use it. This can be useful for adding
    new invisible indexes or making existing indexes invisible before dropping them
    to ensure queries are not negatively affected.
    See https://dev.mysql.com/blog-archive/mysql-8-0-invisible-indexes/ for more details.

    MariaDB 10.6.0 also added support for this feature by allowing indexes to be "ignored"
    in queries. See https://mariadb.com/kb/en/ignored-indexes/ for more details.

    Active Record now supports this option for MySQL 8.0.0+ and MariaDB 10.6.0+ for
    index creation and alteration where the new index option enabled: true/false can be
    passed to column and index methods as below:

    add_index :users, :email, enabled: false
    enable_index :users, :email
    add_column :users, :dob, :string, index: { enabled: false }
    
    change_table :users do |t|
      t.index :name, enabled: false
      t.index :dob
      t.disable_index :dob
      t.column :username, :string, index: { enabled: false }
      t.references :account, index: { enabled: false }
    end
    
    create_table :users do |t|
      t.string :name, index: { enabled: false }
      t.string :email
      t.index :email, enabled: false
    end
    

    Merve Taner

  • Respect implicit_order_column in ActiveRecord::Relation#reverse_order.

    Joshua Young

  • Add column types to ActiveRecord::Result for SQLite3.

    Andrew Kane

  • Raise ActiveRecord::ReadOnlyError when pessimistically locking with a readonly role.

    Joshua Young

  • Fix using the SQLite3Adapter's dbconsole method outside of a Rails application.

    Hartley McGuire

  • Fix migrating multiple databases with ActiveRecord::PendingMigration action.

    Gannon McGibbon

  • Enable automatically retrying idempotent association queries on connection
    errors.

    Hartley McGuire

  • Add allow_retry to sql.active_record instrumentation.

    This enables identifying queries which queries are automatically retryable on connection errors.

    Hartley McGuire

  • Better support UPDATE with JOIN for Postgresql and SQLite3

    Previously when generating update queries with one or more JOIN clauses,
    Active Record would use a sub query which would prevent to reference the joined
    tables in the SET clause, for instance:

    Comment.joins(:post).update_all("title = posts.title")
    

    This is now supported as long as the relation doesn't also use a LIMIT, ORDER or
    GROUP BY clause. This was supported by the MySQL adapter for a long time.

    Jean Boussier

  • Introduce a before-fork hook in ActiveSupport::Testing::Parallelization to clear existing
    connections, to avoid fork-safety issues with the mysql2 adapter.

    Fixes #41776

    Mike Dalessio, Donal McBreen

  • PoolConfig no longer keeps a reference to the connection class.

    Keeping a reference to the class caused subtle issues when combined with reloading in
    development. Fixes #54343.

    Mike Dalessio

  • Fix SQL notifications sometimes not sent when using async queries.

    Post.async_count
    ActiveSupport::Notifications.subscribed(->(*) { "Will never reach here" }) do
      Post.count
    end
    

    In rare circumstances and under the right race condition, Active Support notifications
    would no longer be dispatched after using an asynchronous query.
    This is now fixed.

    Edouard Chin

  • Eliminate queries loading dumped schema cache on Postgres

    Improve resiliency by avoiding needing to open a database connection to load the
    type map while defining attribute methods at boot when a schema cache file is
    configured on PostgreSQL databases.

    James Coleman

  • ActiveRecord::Coder::JSON can be instantiated

    Options can now be passed to ActiveRecord::Coder::JSON when instantiating the coder. This allows:

    serialize :config, coder: ActiveRecord::Coder::JSON.new(symbolize_names: true)
    

    matthaigh27

  • Deprecate using insert_all/upsert_all with unpersisted records in associations.

    Using these methods on associations containing unpersisted records will now
    show a deprecation warning, as the unpersisted records will be lost after
    the operation.

    Nick Schwaderer

  • Make column name optional for index_exists?.

    This aligns well with remove_index signature as well, where
    index name doesn't need to be derived from the column names.

    Ali Ismayiliov

  • Change the payload name of sql.active_record notification for eager
    loading from "SQL" to "#{model.name} Eager Load".

    zzak

  • Enable automatically retrying idempotent #exists? queries on connection
    errors.

    Hartley McGuire, classidied

  • Deprecate usage of unsupported methods in conjunction with update_all:

    update_all will now print a deprecation message if a query includes either WITH,
    WITH RECURSIVE or DISTINCT statements. Those were never supported and were ignored
    when generating the SQL query.

    An error will be raised in a future Rails release. This behavior will be consistent
    with delete_all which currently raises an error for unsupported statements.

    Edouard Chin

  • The table columns inside schema.rb are now sorted alphabetically.

    Previously they'd be sorted by creation order, which can cause merge conflicts when two
    branches modify the same table concurrently.

    John Duff

  • Introduce versions formatter for the schema dumper.

    It is now possible to override how schema dumper formats versions information inside the
    structure.sql file. Currently, the versions are simply sorted in the decreasing order.
    Within large teams, this can potentially cause many merge conflicts near the top of the list.

    Now, the custom formatter can be provided with a custom sorting logic (e.g. by hash values
    of the versions), which can greatly reduce the number of conflicts.

    fatkodima

  • Serialized attributes can now be marked as comparable.

    A not rare issue when working with serialized attributes is that the serialized representation of an object
    can change over time. Either because you are migrating from one serializer to the other (e.g. YAML to JSON or to msgpack),
    or because the serializer used subtly changed its output.

    One example is libyaml that used to have some extra trailing whitespaces, and recently fixed that.
    When this sorts of thing happen, you end up with lots of records that report being changed even though
    they aren't, which in the best case leads to a lot more writes to the database and in the worst case lead to nasty bugs.

    The solution is to instead compare the deserialized representation of the object, however Active Record
    can't assume the deserialized object has a working == method. Hence why this new functionality is opt-in.

    serialize :config, type: Hash, coder: JSON, comparable: true
    

    Jean Boussier

  • Fix MySQL default functions getting dropped when changing a column's nullability.

    Bastian Bartmann

  • SQLite extensions can be configured in config/database.yml.

    The database configuration option extensions: allows an application to load SQLite extensions
    when using sqlite3 >= v2.4.0. The array members may be filesystem paths or the names of
    modules that respond to .to_path:

    development:
      adapter: sqlite3
      extensions:
        - SQLean::UUID                     # module name responding to `.to_path`
        - .sqlpkg/nalgeon/crypto/crypto.so # or a filesystem path
        - <%= AppExtensions.location %>    # or ruby code returning a path
    

    Mike Dalessio

  • ActiveRecord::Middleware::ShardSelector supports granular database connection switching.

    A new configuration option, class_name:, is introduced to
    config.active_record.shard_selector to allow an application to specify the abstract connection
    class to be switched by the shard selection middleware. The default class is
    ActiveRecord::Base.

    For example, this configuration tells ShardSelector to switch shards using
    AnimalsRecord.connected_to:

    config.active_record.shard_selector = { class_name: "AnimalsRecord" }
    

    Mike Dalessio

  • Reset relations after insert_all/upsert_all.

    Bulk insert/upsert methods will now call reset if used on a relation, matching the behavior of update_all.

    Milo Winningham

  • Use _N as a parallel tests databases suffixes

    Peviously, -N was used as a suffix. This can cause problems for RDBMSes
    which do not support dashes in database names.

    fatkodima

  • Remember when a database connection has recently been verified (for
    two seconds, by default), to avoid repeated reverifications during a
    single request.

    This should recreate a similar rate of verification as in Rails 7.1,
    where connections are leased for the duration of a request, and thus
    only verified once.

    Matthew Draper

  • Allow to reset cache counters for multiple records.

    Aircraft.reset_counters([1, 2, 3], :wheels_count)
    

    It produces much fewer queries compared to the custom implementation using looping over ids.
    Previously: O(ids.size * counters.size) queries, now: O(ids.size + counters.size) queries.

    fatkodima

  • Add affected_rows to sql.active_record Notification.

    Hartley McGuire

  • Fix sum when performing a grouped calculation.

    User.group(:friendly).sum no longer worked. This is fixed.

    Edouard Chin

  • Add support for enabling or disabling transactional tests per database.

    A test class can now override the default use_transactional_tests setting
    for individual databases, which can be useful if some databases need their
    current state to be accessible to an external process while tests are running.

    class MostlyTransactionalTest < ActiveSupport::TestCase
      self.use_transactional_tests = true
      skip_transactional_tests_for_database :shared
    end
    

    Matthew Cheetham, Morgan Mareve

  • Cast query_cache value when using URL configuration.

    zzak

  • NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.

    Ryuta Kamizono

  • PG::UnableToSend: no connection to the server is now retryable as a connection-related exception

    Kazuma Watanabe

Action View

  • Allow current_page? to match against specific HTTP method(s) with a method: option.

    Ben Sheldon

  • remove autocomplete="off" on hidden inputs generated by form_tag, token_tag, method_tag, and the hidden
    parameter fields included in button_to forms will omit the autocomplete="off" attribute.

    nkulway

  • Enable configuring the strategy for tracking dependencies between Action
    View templates.

    The existing :regex strategy is kept as the default, but with
    load_defaults 8.1 the strategy will be :ruby (using a real Ruby parser).

    Hartley McGuire

  • Introduce relative_time_in_words helper

    relative_time_in_words(3.minutes.from_now) # => "in 3 minutes"
    relative_time_in_words(3.minutes.ago) # => "3 minutes ago"
    relative_time_in_words(10.seconds.ago, include_seconds: true) # => "less than 10 seconds ago"
    

    Matheus Richard

  • Make nonce: false remove the nonce attribute from javascript_tag, javascript_include_tag, and stylesheet_link_tag.

    francktrouillez

  • Add dom_target helper to create dom_id-like strings from an unlimited
    number of objects.

    Ben Sheldon

  • Respect html_options[:form] when collection_checkboxes generates the
    hidden <input>.

    Riccardo Odone

  • Layouts have access to local variables passed to render.

    This fixes #31680 which was a regression in Rails 5.1.

    Mike Dalessio

  • Argument errors related to strict locals in templates now raise an
    ActionView::StrictLocalsError, and all other argument errors are reraised as-is.

    Previously, any ArgumentError raised during template rendering was swallowed during strict
    local error handling, so that an ArgumentError unrelated to strict locals (e.g., a helper
    method invoked with incorrect arguments) would be replaced by a similar ArgumentError with an
    unrelated backtrace, making it difficult to debug templates.

    Now, any ArgumentError unrelated to strict locals is reraised, preserving the original
    backtrace for developers.

    Also note that ActionView::StrictLocalsError is a subclass of ArgumentError, so any existing
    code that rescues ArgumentError will continue to work.

    Fixes #52227.

    Mike Dalessio

  • Improve error highlighting of multi-line methods in ERB templates or
    templates where the error occurs within a do-end block.

    Martin Emde

  • Fix a crash in ERB template error highlighting when the error occurs on a
    line in the compiled template that is past the end of the source template.

    Martin Emde

  • Improve reliability of ERB template error highlighting.
    Fix infinite loops and crashes in highlighting and
    improve tolerance for alternate ERB handlers.

    Martin Emde

  • Allow hidden_field and hidden_field_tag to accept a custom autocomplete value.

    brendon

  • Add a new configuration content_security_policy_nonce_auto for automatically adding a nonce to the tags affected by the directives specified by the content_security_policy_nonce_directives configuration option.

    francktrouillez

Action Pack

  • Remove deprecated support to a route to multiple paths.

    Rafael Mendonça França

  • Remove deprecated support for using semicolons as a query string separator.

    Before:

    ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
    # => [["foo", "bar"], ["baz", "quux"]]
    

    After:

    ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a
    # => [["foo", "bar;baz=quux"]]
    

    Rafael Mendonça França

  • Remove deprecated support to skipping over leading brackets in parameter names in the parameter parser.

    Before:

    ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" }
    ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }
    

    After:

    ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" }
    ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } }
    

    Rafael Mendonça França

  • Deprecate Rails.application.config.action_dispatch.ignore_leading_brackets.

    Rafael Mendonça França

  • Raise ActionController::TooManyRequests error from ActionController::RateLimiting

    Requests that exceed the rate limit raise an ActionController::TooManyRequests error.
    By default, Action Dispatch rescues the error and responds with a 429 Too Many Requests status.

    Sean Doyle

  • Add .md/.markdown as Markdown extensions and add a default markdown: renderer:

    class Page
      def to_markdown
        body
      end
    end
    
    class PagesController < ActionController::Base
      def show
        @page = Page.find(params[:id])
    
        respond_to do |format|
          format.html
          format.md { render markdown: @page }
        end
      end
    end
    

    DHH

  • Add headers to engine routes inspection command

    Petrik de Heus

  • Add "Copy as text" button to error pages

    Mikkel Malmberg

  • Add scope: option to rate_limit method.

    Previously, it was not possible to share a rate limit count between several controllers, since the count was by
    default separate for each controller.

    Now, the scope: option solves this problem.

    class APIController < ActionController::API
      rate_limit to: 2, within: 2.seconds, scope: "api"
    end
    
    class API::PostsController < APIController
      # ...
    end
    
    class API::UsersController < APIController
      # ...
    end
    

    ArthurPV, Kamil Hanus

  • Add support for rack.response_finished callbacks in ActionDispatch::Executor.

    The executor middleware now supports deferring completion callbacks to later
    in the request lifecycle by utilizing Rack's rack.response_finished mechanism,
    when available. This enables applications to define rack.response_finished callbacks
    that may rely on state that would be cleaned up by the executor's completion callbacks.

    Adrianna Chang, Hartley McGuire

  • Produce a log when rescue_from is invoked.

    Steven Webb, Jean Boussier

  • Allow hosts redirects from hosts Rails configuration

    config.action_controller.allowed_redirect_hosts << "example.com"
    

    Kevin Robatel

  • rate_limit.action_controller notification has additional payload

    additional values: count, to, within, by, name, cache_key

    Jonathan Rochkind

  • Add JSON support to the built-in health controller.

    The health controller now responds to JSON requests with a structured response
    containing status and timestamp information. This makes it easier for monitoring
    tools and load balancers to consume health check data programmatically.

    # /up.json
    {
      "status": "up",
      "timestamp": "2025-09-19T12:00:00Z"
    }
    

    Francesco Loreti, Juan Vásquez

  • Allow to open source file with a crash from the browser.

    Igor Kasyanchuk

  • Always check query string keys for valid encoding just like values are checked.

    Casper Smits

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

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

    Hartley McGuire

  • Add comprehensive support for HTTP Cache-Control request directives according to RFC 9111.

    Provides a request.cache_control_directives object that gives access to request cache directives:

    # Boolean directives
    request.cache_control_directives.only_if_cached?  # => true/false
    request.cache_control_directives.no_cache?        # => true/false
    request.cache_control_directives.no_store?        # => true/false
    request.cache_control_directives.no_transform?    # => true/false
    
    # Value directives
    request.cache_control_directives.max_age          # => integer or nil
    request.cache_control_directives.max_stale        # => integer or nil (or true for valueless max-stale)
    request.cache_control_directives.min_fresh        # => integer or nil
    request.cache_control_directives.stale_if_error   # => integer or nil
    
    # Special helpers for max-stale
    request.cache_control_directives.max_stale?         # => true if max-stale present (with or without value)
    request.cache_control_directives.max_stale_unlimited? # => true only for valueless max-stale
    

    Example usage:

    def show
      if request.cache_control_directives.only_if_cached?
        @article = Article.find_cached(params[:id])
        return head(:gateway_timeout) if @article.nil?
      else
        @article = Article.find(params[:id])
      end
    
      render :show
    end
    

    egg528

  • Add assert_in_body/assert_not_in_body as the simplest way to check if a piece of text is in the response body.

    DHH

  • Include cookie name when calculating maximum allowed size.

    Hartley McGuire

  • Implement must-understand directive according to RFC 9111.

    The must-understand directive indicates that a cache must understand the semantics of the response status code, or discard the response. This directive is enforced to be used only with no-store to ensure proper cache behavior.

    class ArticlesController < ApplicationController
      def show
        @article = Article.find(params[:id])
    
        if @article.special_format?
          must_understand
          render status: 203 # Non-Authoritative Information
        else
          fresh_when @article
        end
      end
    end
    

    heka1024

  • The JSON renderer doesn't escape HTML entities or Unicode line separators anymore.

    Using render json: will no longer escape <, >, &, U+2028 and U+2029 characters that can cause errors
    when the resulting JSON is embedded in JavaScript, or vulnerabilities when the resulting JSON is embedded in HTML.

    Since the renderer is used to return a JSON document as application/json, it's typically not necessary to escape
    those characters, and it improves performance.

    Escaping will still occur when the :callback option is set, since the JSON is used as JavaScript code in this
    situation (JSONP).

    You can use the :escape option or set config.action_controller.escape_json_responses to true to restore the
    escaping behavior.

    class PostsController < ApplicationController
      def index
        render json: Post.last(30), escape: true
      end
    end
    

    Étienne Barrié, Jean Boussier

  • Load lazy route sets before inserting test routes

    Without loading lazy route sets early, we miss after_routes_loaded callbacks, or risk
    invoking them with the test routes instead of the real ones if another load is triggered by an engine.

    Gannon McGibbon

  • Raise AbstractController::DoubleRenderError if head is called after rendering.

    After this change, invoking head will lead to an error if response body is already set:

    class PostController < ApplicationController
      def index
        render locals: {}
        head :ok
      end
    end
    

    Iaroslav Kurbatov

  • The Cookie Serializer can now serialize an Active Support SafeBuffer when using message pack.

    Such code would previously produce an error if an application was using messagepack as its cookie serializer.

    class PostController < ApplicationController
      def index
        flash.notice = t(:hello_html) # This would try to serialize a SafeBuffer, which was not possible.
      end
    end
    

    Edouard Chin

  • 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

  • Add resource name to the ArgumentError that's raised when invalid :only or :except options are given to #resource or #resources

    This makes it easier to locate the source of the problem, especially for routes drawn by gems.

    Before:

    :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    After:

    Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    Jeremy Green

  • A route pointing to a non-existing controller now returns a 500 instead of a 404.

    A controller not existing isn't a routing error that should result
    in a 404, but a programming error that should result in a 500 and
    be reported.

    Until recently, this was hard to untangle because of the support
    for dynamic :controller segment in routes, but since this is
    deprecated and will be removed in Rails 8.1, we can now easily
    not consider missing controllers as routing errors.

    Jean Boussier

  • Add check_collisions option to ActionDispatch::Session::CacheStore.

    Newly generated session ids use 128 bits of randomness, which is more than
    enough to ensure collisions can't happen, but if you need to harden sessions
    even more, you can enable this option to check in the session store that the id
    is indeed free you can enable that option. This however incurs an extra write
    on session creation.

    Shia

  • In ExceptionWrapper, match backtrace lines with built templates more often,
    allowing improved highlighting of errors within do-end blocks in templates.
    Fix for Ruby 3.4 to match new method labels in backtrace.

    Martin Emde

  • Allow setting content type with a symbol of the Mime type.

    # Before
    response.content_type = "text/html"
    
    # After
    response.content_type = :html
    

    Petrik de Heus

Active Job

  • Deprecate built-in sidekiq adapter.

    If you're using this adapter, upgrade to sidekiq 7.3.3 or later to use the sidekiq gem's adapter.

    fatkodima

  • Remove deprecated internal SuckerPunch adapter in favor of the adapter included with the sucker_punch gem.

    Rafael Mendonça França

  • Remove support to set ActiveJob::Base.enqueue_after_transaction_commit to :never, :always and :default.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.active_job.enqueue_after_transaction_commit.

    Rafael Mendonça França

  • ActiveJob::Serializers::ObjectSerializers#klass method is now public.

    Custom Active Job serializers must have a public #klass method too.
    The returned class will be index allowing for faster serialization.

    Jean Boussier

  • Allow jobs to the interrupted and resumed with Continuations

    A job can use Continuations by including the ActiveJob::Continuable
    concern. Continuations split jobs into steps. When the queuing system
    is shutting down jobs can be interrupted and their progress saved.

    class ProcessImportJob
      include ActiveJob::Continuable
    
      def perform(import_id)
        @import = Import.find(import_id)
    
        # block format
        step :initialize do
          @import.initialize
        end
    
        # step with cursor, the cursor is saved when the job is interrupted
        step :process do |step|
          @import.records.find_each(start: step.cursor) do |record|
            record.process
            step.advance! from: record.id
          end
        end
    
        # method format
        step :finalize
    
        private
          def finalize
            @import.finalize
          end
      end
    end
    

    Donal McBreen

  • Defer invocation of ActiveJob enqueue callbacks until after commit when
    enqueue_after_transaction_commit is enabled.

    Will Roever

  • Add report: option to ActiveJob::Base#retry_on and #discard_on

    When the report: option is passed, errors will be reported to the error reporter
    before being retried / discarded.

    Andrew Novoselac

  • Accept a block for ActiveJob::ConfiguredJob#perform_later.

    This was inconsistent with a regular ActiveJob::Base#perform_later.

    fatkodima

  • Raise a more specific error during deserialization when a previously serialized job class is now unknown.

    ActiveJob::UnknownJobClassError will be raised instead of a more generic
    NameError to make it easily possible for adapters to tell if the NameError
    was raised during job execution or deserialization.

    Earlopain

Action Mailer

  • Add deliver_all_later to enqueue multiple emails at once.

    user_emails = User.all.map { |user| Notifier.welcome(user) }
    ActionMailer.deliver_all_later(user_emails)
    
    # use a custom queue
    ActionMailer.deliver_all_later(user_emails, queue: :my_queue)
    

    This can greatly reduce the number of round-trips to the queue datastore.
    For queue adapters that do not implement the enqueue_all method, we
    fall back to enqueuing email jobs indvidually.

    fatkodima

Action Cable

  • Allow passing composite channels to ActionCable::Channel#stream_for – e.g. stream_for [ group, group.owner ]

    hey-leon

  • Allow setting nil as subscription connection identifier for Redis.

    Nguyen Nguyen

Active Storage

  • Remove deprecated :azure storage service.

    Rafael Mendonça França

  • Remove unnecessary calls to the GCP metadata server.

    Calling Google::Auth.get_application_default triggers an explicit call to
    the metadata server - given it was being called for significant number of
    file operations, it can lead to considerable tail latencies and even metadata
    server overloads. Instead, it's preferable (and significantly more efficient)
    that applications use:

    Google::Apis::RequestOptions.default.authorization = Google::Auth.get_application_default(...)
    

    In the cases applications do not set that, the GCP libraries automatically determine credentials.

    This also enables using credentials other than those of the associated GCP
    service account like when using impersonation.

    Alex Coomans

  • Direct upload progress accounts for server processing time.

    Jeremy Daer

  • Delegate ActiveStorage::Filename#to_str to #to_s

    Supports checking String equality:

    filename = ActiveStorage::Filename.new("file.txt")
    filename == "file.txt" # => true
    filename in "file.txt" # => true
    "file.txt" == filename # => true
    

    Sean Doyle

  • Add support for alternative MD5 implementation through config.active_storage.checksum_implementation.

    Also automatically degrade to using the slower Digest::MD5 implementation if OpenSSL::Digest::MD5
    is found to be disabled because of OpenSSL FIPS mode.

    Matt Pasquini, Jean Boussier

  • A Blob will no longer autosave associated Attachment.

    This fixes an issue where a record with an attachment would have
    its dirty attributes reset, preventing your after commit callbacks
    on that record to behave as expected.

    Note that this change doesn't require any changes on your application
    and is supposed to be internal. Active Storage Attachment will continue
    to be autosaved (through a different relation).

    Edouard-chin

Action Mailbox

  • Add reply_to_address extension method on Mail::Message.

    Mr0grog

Action Text

  • Forward fill_in_rich_text_area options to Capybara

    fill_in_rich_textarea "Rich text editor", id: "trix_editor_1", with: "Hello world!"
    

    Sean Doyle

  • Attachment upload progress accounts for server processing time.

    Jeremy Daer

  • The Trix dependency is now satisfied by a gem, action_text-trix, rather than vendored
    files. This allows applications to bump Trix versions independently of Rails
    releases. Effectively this also upgrades Trix to >= 2.1.15.

    Mike Dalessio

  • Change ActionText::RichText#embeds assignment from before_save to before_validation

    Sean Doyle

Railties

  • Add command rails credentials:fetch PATH to get the value of a credential from the credentials file.

    $ bin/rails credentials:fetch kamal_registry.password
    

    Matthew Nguyen, Jean Boussier

  • Generate static BCrypt password digests in fixtures instead of dynamic ERB expressions.

    Previously, fixtures with password digest attributes used <%= BCrypt::Password.create("secret") %>,
    which regenerated the hash on each test run. Now generates a static hash with a comment
    showing how to recreate it.

    Nate Smith, Cassia Scheffer

  • Broaden the .gitignore entry when adding a credentials key to ignore all key files.

    Greg Molnar

  • Remove unnecessary ruby-version input from ruby/setup-ruby

    TangRufus

  • Add --reset option to bin/setup which will call db:reset as part of the setup.

    DHH

  • Add RuboCop cache restoration to RuboCop job in GitHub Actions workflow templates.

    Lovro Bikić

  • Skip generating mailer-related files in authentication generator if the application does
    not use ActionMailer

    Rami Massoud

  • Introduce bin/ci for running your tests, style checks, and security audits locally or in the cloud.

    The specific steps are defined by a new DSL in config/ci.rb.

    ActiveSupport::ContinuousIntegration.run do
      step "Setup", "bin/setup --skip-server"
      step "Style: Ruby", "bin/rubocop"
      step "Security: Gem audit", "bin/bundler-audit"
      step "Tests: Rails", "bin/rails test test:system"
    end
    

    Optionally use gh-signoff to
    set a green PR status - ready for merge.

    Jeremy Daer, DHH

  • Generate session controller tests when running the authentication generator.

    Jerome Dalbert

  • Add bin/bundler-audit and config/bundler-audit.yml for discovering and managing known security problems with app gems.

    DHH

  • Rails no longer generates a bin/bundle binstub when creating new applications.

    The bin/bundle binstub used to help activate the right version of bundler.
    This is no longer necessary as this mechanism is now part of Rubygem itself.

    Edouard Chin

  • Add a SessionTestHelper module with sign_in_as(user) and sign_out test helpers when
    running rails g authentication. Simplifies authentication in integration tests.

    Bijan Rahnema

  • Rate limit password resets in authentication generator

    This helps mitigate abuse from attackers spamming the password reset form.

    Chris Oliver

  • Update rails new --minimal option

    Extend the --minimal flag to exclude recently added features:
    skip_brakeman, skip_ci, skip_docker, skip_kamal, skip_rubocop, skip_solid and skip_thruster.

    eelcoj

  • Add application-name metadata to application layout

    The following metatag will be added to app/views/layouts/application.html.erb

    <meta name="application-name" content="Name of Rails Application">
    

    Steve Polito

  • Use secret_key_base from ENV or credentials when present locally.

    When ENV["SECRET_KEY_BASE"] or
    Rails.application.credentials.secret_key_base is set for test or
    development, it is used for the Rails.config.secret_key_base,
    instead of generating a tmp/local_secret.txt file.

    Petrik de Heus

  • Introduce RAILS_MASTER_KEY placeholder in generated ci.yml files

    Steve Polito

  • Colorize the Rails console prompt even on non standard environments.

    Lorenzo Zabot

  • Don't enable YJIT in development and test environments

    Development and test environments tend to reload code and redefine methods (e.g. mocking),
    hence YJIT isn't generally faster in these environments.

    Ali Ismayilov, Jean Boussier

  • Only include PermissionsPolicy::Middleware if policy is configured.

    Petrik de Heus

Guides

  • In the Active Job bug report template set the queue adapter to the
    test adapter so that assert_enqueued_with can pass.

    Andrew White

  • Ensure all bug report templates set config.secret_key_base to avoid
    generation of tmp/local_secret.txt files when running the report template.

    Andrew White

- Ruby
Published by rafaelfranca 6 months ago

https://github.com/rails/rails - 8.0.2.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Call inspect on ids in RecordNotFound error

    [CVE-2025-55193]

    Gannon McGibbon, John Hawthorn

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

Remove dangerous transformations

[CVE-2025-24293]

*Zack Deveau*

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn 7 months ago

https://github.com/rails/rails - 7.2.2.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Call inspect on ids in RecordNotFound error

    [CVE-2025-55193]

    Gannon McGibbon, John Hawthorn

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

Remove dangerous transformations

[CVE-2025-24293]

*Zack Deveau*

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn 7 months ago

https://github.com/rails/rails - 7.1.5.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Call inspect on ids in RecordNotFound error

    [CVE-2025-55193]

    Gannon McGibbon, John Hawthorn

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

Remove dangerous transformations

[CVE-2025-24293]

*Zack Deveau*

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn 7 months ago

https://github.com/rails/rails - 8.0.2

Active Support

  • Fix setting to_time_preserves_timezone from new_framework_defaults_8_0.rb.

    fatkodima

  • 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

Active Model

  • No changes.

Active Record

  • Fix inverting rename_enum_value when :from/:to are provided.

    fatkodima

  • Prevent persisting invalid record.

    Edouard Chin

  • Fix inverting drop_table without options.

    fatkodima

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

    Ryuta Kamizono

  • Fix sum with qualified name on loaded relation.

    Chris Gunther

  • The SQLite3 adapter quotes non-finite Numeric values like "Infinity" and "NaN".

    Mike Dalessio

  • Handle libpq returning a database version of 0 on no/bad connection in PostgreSQLAdapter.

    Before, this version would be cached and an error would be raised during connection configuration when
    comparing it with the minimum required version for the adapter. This meant that the connection could
    never be successfully configured on subsequent reconnection attempts.

    Now, this is treated as a connection failure consistent with libpq, raising a ActiveRecord::ConnectionFailed
    and ensuring the version isn't cached, which allows the version to be retrieved on the next connection attempt.

    Joshua Young, Rian McGuire

  • 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 nil or TypeError: wrong argument type nil (expected PG::TypeMap)`.

    Jean Boussier

  • Fix a case where a non-retryable query could be marked retryable.

    Hartley McGuire

  • Handle circular references when autosaving associations.

    zzak

  • PoolConfig no longer keeps a reference to the connection class.

    Keeping a reference to the class caused subtle issues when combined with reloading in
    development. Fixes #54343.

    Mike Dalessio

  • Fix SQL notifications sometimes not sent when using async queries.

    Post.async_count
    ActiveSupport::Notifications.subscribed(->(*) { "Will never reach here" }) do
      Post.count
    end
    

    In rare circumstances and under the right race condition, Active Support notifications
    would no longer be dispatched after using an asynchronous query.
    This is now fixed.

    Edouard Chin

  • Fix support for PostgreSQL enum types with commas in their name.

    Arthur Hess

  • Fix inserts on MySQL with no RETURNING support for a table with multiple auto populated columns.

    Nikita Vasilevsky

  • Fix joining on a scoped association with string joins and bind parameters.

    class Instructor < ActiveRecord::Base
      has_many :instructor_roles, -> { active }
    end
    
    class InstructorRole < ActiveRecord::Base
      scope :active, -> {
        joins("JOIN students ON instructor_roles.student_id = students.id")
        .where(students { status: 1 })
      }
    end
    
    Instructor.joins(:instructor_roles).first
    

    The above example would result in ActiveRecord::StatementInvalid because the
    active scope bind parameters would be lost.

    Jean Boussier

  • Fix a potential race condition with system tests and transactional fixtures.

    Sjoerd Lagarde

  • Fix autosave associations to no longer validated unmodified associated records.

    Active Record was incorrectly performing validation on associated record that
    weren't created nor modified as part of the transaction:

    Post.create!(author: User.find(1)) # Fail if user is invalid
    

    Jean Boussier

  • Remember when a database connection has recently been verified (for
    two seconds, by default), to avoid repeated reverifications during a
    single request.

    This should recreate a similar rate of verification as in Rails 7.1,
    where connections are leased for the duration of a request, and thus
    only verified once.

    Matthew Draper

Action View

  • Respect html_options[:form] when collection_checkboxes generates the
    hidden <input>.

    Riccardo Odone

  • Layouts have access to local variables passed to render.

    This fixes #31680 which was a regression in Rails 5.1.

    Mike Dalessio

  • Argument errors related to strict locals in templates now raise an
    ActionView::StrictLocalsError, and all other argument errors are reraised as-is.

    Previously, any ArgumentError raised during template rendering was swallowed during strict
    local error handling, so that an ArgumentError unrelated to strict locals (e.g., a helper
    method invoked with incorrect arguments) would be replaced by a similar ArgumentError with an
    unrelated backtrace, making it difficult to debug templates.

    Now, any ArgumentError unrelated to strict locals is reraised, preserving the original
    backtrace for developers.

    Also note that ActionView::StrictLocalsError is a subclass of ArgumentError, so any existing
    code that rescues ArgumentError will continue to work.

    Fixes #52227.

    Mike Dalessio

  • Fix stack overflow error in dependency tracker when dealing with circular dependencies

    Jean Boussier

Action Pack

  • Improve with_routing test helper to not rebuild the middleware stack.

    Otherwise some middleware configuration could be lost.

    Édouard Chin

  • Add resource name to the ArgumentError that's raised when invalid :only or :except options are given to #resource or #resources

    This makes it easier to locate the source of the problem, especially for routes drawn by gems.

    Before:

    :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    After:

    Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
    

    Jeremy Green

  • Fix url_for to handle :path_params gracefully when it's not a Hash.

    Prevents various security scanners from causing exceptions.

    Martin Emde

  • Fix ActionDispatch::Executor to unwrap exceptions like other error reporting middlewares.

    Jean Boussier

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • A Blob will no longer autosave associated Attachment.

    This fixes an issue where a record with an attachment would have
    its dirty attributes reset, preventing your after commit callbacks
    on that record to behave as expected.

    Note that this change doesn't require any changes on your application
    and is supposed to be internal. Active Storage Attachment will continue
    to be autosaved (through a different relation).

    Edouard-chin

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Fix Rails console to load routes.

    Otherwise *_path and *url methods are missing on the app object.

    Édouard Chin

  • Update rails new --minimal option

    Extend the --minimal flag to exclude recently added features:
    skip_brakeman, skip_ci, skip_docker, skip_kamal, skip_rubocop, skip_solid and skip_thruster.

    eelcoj

  • Use secret_key_base from ENV or credentials when present locally.

    When ENV["SECRET_KEY_BASE"] or
    Rails.application.credentials.secret_key_base is set for test or
    development, it is used for the Rails.config.secret_key_base,
    instead of generating a tmp/local_secret.txt file.

    Petrik de Heus

Guides

  • No changes.

- Ruby
Published by rafaelfranca 12 months ago

https://github.com/rails/rails - 8.0.1

Active Support

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

    Martin Emde

  • Restore the ability to decorate methods generated by class_attribute.

    It always has been complicated to use Module#prepend or an alias method chain
    to decorate methods defined by class_attribute, but became even harder in 8.0.

    This capability is now supported for both reader and writer methods.

    Jean Boussier

Active Model

  • No changes.

Active Record

  • Fix removing foreign keys with :restrict action for MySQ

    fatkodima

  • 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

  • Fix MySQL default functions getting dropped when changing a column's nullability.

    Bastian Bartmann

  • Fix add_unique_constraint/add_check_constraint/add_foreign_key to be revertible when given invalid options.

    fatkodima

  • Fix asynchronous destroying of polymorphic belongs_to associations.

    fatkodima

  • Fix insert_all to not update existing records.

    fatkodima

  • NOT VALID constraints should not dump in create_table.

    Ryuta Kamizono

  • Fix finding by nil composite primary key association.

    fatkodima

  • Properly reset composite primary key configuration when setting a primary key.

    fatkodima

  • Fix Mysql2Adapter support for prepared statements

    Using prepared statements with MySQL could result in a NoMethodError exception.

    Jean Boussier, Leo Arnold, zzak

  • Fix parsing of SQLite foreign key names when they contain non-ASCII characters

    Zacharias Knudsen

  • Fix parsing of MySQL 8.0.16+ CHECK constraints when they contain new lines.

    Steve Hill

  • Ensure normalized attribute queries use IS NULL consistently for nil and normalized nil values.

    Joshua Young

  • Fix sum when performing a grouped calculation.

    User.group(:friendly).sum no longer worked. This is fixed.

    Edouard Chin

  • Restore back the ability to pass only database name to DATABASE_URL.

    fatkodima

Action View

  • Fix a crash in ERB template error highlighting when the error occurs on a
    line in the compiled template that is past the end of the source template.

    Martin Emde

  • Improve reliability of ERB template error highlighting.
    Fix infinite loops and crashes in highlighting and
    improve tolerance for alternate ERB handlers.

    Martin Emde

Action Pack

  • Add ActionDispatch::Request::Session#store method to conform Rack spec.

    Yaroslav

Active Job

  • Avoid crashing in Active Job logger when logging enqueueing errors

    ActiveJob.perform_all_later could fail with a TypeError when all
    provided jobs failed to be enqueueed.

    Efstathios Stivaros

Action Mailer

  • No changes.

Action Cable

  • Ensure the Postgresql adapter always use a dedicated connection even during system tests.

    Fix an issue with the Action Cable Postgresql adapter causing deadlock or various weird
    pg client error during system tests.

    Jean Boussier

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Skip generation system tests related code for CI when --skip-system-test is given.

    fatkodima

  • Don't add bin/thrust if thruster is not in Gemfile.

    Étienne Barrié

  • Don't install a package for system test when applications don't use it.

    y-yagi

Guides

  • No changes.

- Ruby
Published by rafaelfranca about 1 year ago

https://github.com/rails/rails - 8.0.0.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Add validation to content security policies to disallow spaces and semicolons.
    Developers should use multiple arguments, and different directive methods instead.

    [CVE-2024-54133]

    Gannon McGibbon

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Update vendored trix version to 2.1.10

    John Hawthorn

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn about 1 year ago

https://github.com/rails/rails - 7.2.2.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Add validation to content security policies to disallow spaces and semicolons.
    Developers should use multiple arguments, and different directive methods instead.

    [CVE-2024-54133]

    Gannon McGibbon

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Update vendored trix version to 2.1.10

    John Hawthorn

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn about 1 year ago

https://github.com/rails/rails - 7.1.5.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Add validation to content security policies to disallow spaces and semicolons.
    Developers should use multiple arguments, and different directive methods instead.

    [CVE-2024-54133]

    Gannon McGibbon

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Update vendored trix version to 2.1.10

    John Hawthorn

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn about 1 year ago

https://github.com/rails/rails - 7.0.8.7

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Add validation to content security policies to disallow spaces and semicolons.
    Developers should use multiple arguments, and different directive methods instead.

    [CVE-2024-54133]

    Gannon McGibbon

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Update vendored trix version to 1.3.4

    John Hawthorn

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn about 1 year ago

https://github.com/rails/rails - 8.0.0

Active Support

  • Remove deprecated support to passing an array of strings to ActiveSupport::Deprecation#warn.

    Rafael Mendonça França

  • Remove deprecated support to setting attr_internal_naming_format with a @ prefix.

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::ProxyObject.

    Rafael Mendonça França

  • Don't execute i18n watcher on boot. It shouldn't catch any file changes initially,
    and unnecessarily slows down boot of applications with lots of translations.

    Gannon McGibbon, David Stosik

  • Fix ActiveSupport::HashWithIndifferentAccess#stringify_keys to stringify all keys not just symbols.

    Previously:

    { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
    

    After this change:

    { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
    

    This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
    to not backport the fix and to make the change in a major release.

    Jean Boussier

  • Include options when instrumenting ActiveSupport::Cache::Store#delete and ActiveSupport::Cache::Store#delete_multi.

    Adam Renberg Tamm

  • Print test names when running rails test -v for parallel tests.

    John Hawthorn, Abeid Ahmed

  • Deprecate Benchmark.ms core extension.

    The benchmark gem will become bundled in Ruby 3.5

    Earlopain

  • ActiveSupport::TimeWithZone#inspect now uses ISO 8601 style time like Time#inspect

    John Hawthorn

  • ActiveSupport::ErrorReporter#report now assigns a backtrace to unraised exceptions.

    Previously reporting an un-raised exception would result in an error report without
    a backtrace. Now it automatically generates one.

    Jean Boussier

  • Add escape_html_entities option to ActiveSupport::JSON.encode.

    This allows for overriding the global configuration found at
    ActiveSupport.escape_html_entities_in_json for specific calls to to_json.

    This should be usable from controllers in the following manner:

    class MyController < ApplicationController
      def index
        render json: { hello: "world" }, escape_html_entities: false
      end
    end
    

    Nigel Baillie

  • Raise when using key which can't respond to #to_sym in EncryptedConfiguration.

    As is the case when trying to use an Integer or Float as a key, which is unsupported.

    zzak

  • Deprecate addition and since between two Time and ActiveSupport::TimeWithZone.

    Previously adding time instances together such as 10.days.ago + 10.days.ago or 10.days.ago.since(10.days.ago) produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.

    Nick Schwaderer

  • Support rfc2822 format for Time#to_fs & Date#to_fs.

    Akshay Birajdar

  • Optimize load time for Railtie#initialize_i18n. Filter I18n.load_paths passed to the file watcher to only those
    under Rails.root. Previously the watcher would grab all available locales, including those in gems
    which do not require a watcher because they won't change.

    Nick Schwaderer

  • Add a filter option to in_order_of to prioritize certain values in the sorting without filtering the results
    by these values.

    Igor Depolli

  • Improve error message when using assert_difference or assert_changes with a
    proc by printing the proc's source code (MRI only).

    Richard Böhme, Jean Boussier

  • Add a new configuration value :zone for ActiveSupport.to_time_preserves_timezone and rename the previous true value to :offset. The new default value is :zone.

    Jason Kim, John Hawthorn

  • Align instrumentation payload[:key] in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys.

    Frederik Erbs Spang Thomsen

  • Fix travel_to to set usec 0 when with_usec is false and the given argument String or DateTime.

    mopp

Active Model

  • Add :except_on option for validations. Grants the ability to skip validations in specified contexts.

    class User < ApplicationRecord
        #...
        validates :birthday, presence: { except_on: :admin }
        #...
    end
    
    user = User.new(attributes except birthday)
    user.save(context: :admin)
    

    Drew Bragg

  • Make ActiveModel::Serialization#read_attribute_for_serialization public

    Sean Doyle

  • Add a default token generator for password reset tokens when using has_secure_password.

    class User < ApplicationRecord
      has_secure_password
    end
    
    user = User.create!(name: "david", password: "123", password_confirmation: "123")
    token = user.password_reset_token
    User.find_by_password_reset_token(token) # returns user
    
    # 16 minutes later...
    User.find_by_password_reset_token(token) # returns nil
    
    # raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
    User.find_by_password_reset_token!(token)
    

    DHH

  • Add a load hook active_model_translation for ActiveModel::Translation.

    Shouichi Kamiya

  • Add raise_on_missing_translations option to ActiveModel::Translation.
    When the option is set, human_attribute_name raises an error if a translation of the given attribute is missing.

    # ActiveModel::Translation.raise_on_missing_translations = false
    Post.human_attribute_name("title")
    => "Title"
    
    # ActiveModel::Translation.raise_on_missing_translations = true
    Post.human_attribute_name("title")
    => Translation missing. Options considered were: (I18n::MissingTranslationData)
        - en.activerecord.attributes.post.title
        - en.attributes.title
    
                raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Shouichi Kamiya

  • Introduce ActiveModel::AttributeAssignment#attribute_writer_missing

    Provide instances with an opportunity to gracefully handle assigning to an
    unknown attribute:

    class Rectangle
      include ActiveModel::AttributeAssignment
    
      attr_accessor :length, :width
    
      def attribute_writer_missing(name, value)
        Rails.logger.warn "Tried to assign to unknown attribute #{name}"
      end
    end
    
    rectangle = Rectangle.new
    rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
    

    Sean Doyle

Active Record

  • Fix support for query_cache: false in database.yml.

    query_cache: false would no longer entirely disable the Active Record query cache.

    zzak

  • NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.

    Ryuta Kamizono

  • The db:prepare task no longer loads seeds when a non-primary database is created.

    Previously, the db:prepare task would load seeds whenever a new database
    is created, leading to potential loss of data if a database is added to an
    existing environment.

    Introduces a new database config property seeds to control whether seeds
    are loaded during db:prepare which defaults to true for primary database
    configs and false otherwise.

    Fixes #53348.

    Mike Dalessio

  • PG::UnableToSend: no connection to the server is now retryable as a connection-related exception

    Kazuma Watanabe

  • Fix strict loading propagation even if statement cache is not used.

    Ryuta Kamizono

  • Allow rename_enum accepts two from/to name arguments as rename_table does so.

    Ryuta Kamizono

  • Remove deprecated support to setting ENV["SCHEMA_CACHE"].

    Rafael Mendonça França

  • Remove deprecated support to passing a database name to cache_dump_filename.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::ConnectionPool#connection.

    Rafael Mendonça França

  • Remove deprecated config.active_record.sqlite3_deprecated_warning.

    Rafael Mendonça França

  • Remove deprecated config.active_record.warn_on_records_fetched_greater_than.

    Rafael Mendonça França

  • Remove deprecated support for defining enum with keyword arguments.

    Rafael Mendonça França

  • Remove deprecated support to finding database adapters that aren't registered to Active Record.

    Rafael Mendonça França

  • Remove deprecated config.active_record.allow_deprecated_singular_associations_name.

    Rafael Mendonça França

  • Remove deprecated config.active_record.commit_transaction_on_non_local_return.

    Rafael Mendonça França

  • Fix incorrect SQL query when passing an empty hash to ActiveRecord::Base.insert.

    David Stosik

  • Allow to save records with polymorphic join tables that have inverse_of
    specified.

    Markus Doits

  • Fix association scopes applying on the incorrect join when using a polymorphic has_many through:.

    Joshua Young

  • Allow ActiveRecord::Base#pluck to accept hash arguments with symbol and string values.

    Post.joins(:comments).pluck(:id, comments: :id)
    Post.joins(:comments).pluck("id", "comments" => "id")
    

    Joshua Young

  • Make Float distinguish between float4 and float8 in PostgreSQL.

    Fixes #52742

    Ryota Kitazawa, Takayuki Nagatomi

  • Allow drop_table to accept an array of table names.

    This will let you to drop multiple tables in a single call.

    ActiveRecord::Base.lease_connection.drop_table(:users, :posts)
    

    Gabriel Sobrinho

  • Add support for PostgreSQL IF NOT EXISTS via the :if_not_exists option
    on the add_enum_value method.

    Ariel Rzezak

  • When running db:migrate on a fresh database, load the databases schemas before running migrations.

    Andrew Novoselac, Marek Kasztelnik

  • Fix an issue where .left_outer_joins used with multiple associations that have
    the same child association but different parents does not join all parents.

    Previously, using .left_outer_joins with the same child association would only join one of the parents.

    Now it will correctly join both parents.

    Fixes #41498.

    Garrett Blehm

  • Deprecate unsigned_float and unsigned_decimal short-hand column methods.

    As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE,
    and DECIMAL. Consider using a simple CHECK constraint instead for such columns.

    https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html

    Ryuta Kamizono

  • Drop MySQL 5.5 support.

    MySQL 5.5 is the only version that does not support datetime with precision,
    which we have supported in the core. Now we support MySQL 5.6.4 or later, which
    is the first version to support datetime with precision.

    Ryuta Kamizono

  • Make Active Record asynchronous queries compatible with transactional fixtures.

    Previously transactional fixtures would disable asynchronous queries, because transactional
    fixtures impose all queries use the same connection.

    Now asynchronous queries will use the connection pinned by transactional fixtures, and behave
    much closer to production.

    Jean Boussier

  • Deserialize binary data before decrypting

    This ensures that we call PG::Connection.unescape_bytea on PostgreSQL before decryption.

    Donal McBreen

  • Ensure ActiveRecord::Encryption.config is always ready before access.

    Previously, ActiveRecord::Encryption configuration was deferred until ActiveRecord::Base
    was loaded. Therefore, accessing ActiveRecord::Encryption.config properties before
    ActiveRecord::Base was loaded would give incorrect results.

    ActiveRecord::Encryption now has its own loading hook so that its configuration is set as
    soon as needed.

    When ActiveRecord::Base is loaded, even lazily, it in turn triggers the loading of
    ActiveRecord::Encryption, thus preserving the original behavior of having its config ready
    before any use of ActiveRecord::Base.

    Maxime Réty

  • Add TimeZoneConverter#== method, so objects will be properly compared by
    their type, scale, limit & precision.

    Address #52699.

    Ruy Rocha

  • Add support for SQLite3 full-text-search and other virtual tables.

    Previously, adding sqlite3 virtual tables messed up schema.rb.

    Now, virtual tables can safely be added using create_virtual_table.

    Zacharias Knudsen

  • Support use of alternative database interfaces via the database_cli ActiveRecord configuration option.

    Rails.application.configure do
      config.active_record.database_cli = { postgresql: "pgcli" }
    end
    

    T S Vallender

  • Add support for dumping table inheritance and native partitioning table definitions for PostgeSQL adapter

    Justin Talbott

  • Add support for ActiveRecord::Point type casts using Hash values

    This allows ActiveRecord::Point to be cast or serialized from a hash
    with :x and :y keys of numeric values, mirroring the functionality of
    existing casts for string and array values. Both string and symbol keys are
    supported.

    class PostgresqlPoint < ActiveRecord::Base
      attribute :x, :point
      attribute :y, :point
      attribute :z, :point
    end
    
    val = PostgresqlPoint.new({
      x: '(12.34, -43.21)',
      y: [12.34, '-43.21'],
      z: {x: '12.34', y: -43.21}
    })
    ActiveRecord::Point.new(12.32, -43.21) == val.x == val.y == val.z
    

    Stephen Drew

  • Replace SQLite3::Database#busy_timeout with #busy_handler_timeout=.

    Provides a non-GVL-blocking, fair retry interval busy handler implementation.

    Stephen Margheim

  • SQLite3Adapter: Translate SQLite3::BusyException into ActiveRecord::StatementTimeout.

    Matthew Nguyen

  • Include schema name in enable_extension statements in db/schema.rb.

    The schema dumper will now include the schema name in generated
    enable_extension statements if they differ from the current schema.

    For example, if you have a migration:

    enable_extension "heroku_ext.pgcrypto"
    enable_extension "pg_stat_statements"
    

    then the generated schema dump will also contain:

    enable_extension "heroku_ext.pgcrypto"
    enable_extension "pg_stat_statements"
    

    Tony Novak

  • Fix ActiveRecord::Encryption::EncryptedAttributeType#type to return
    actual cast type.

    Vasiliy Ermolovich

  • SQLite3Adapter: Bulk insert fixtures.

    Previously one insert command was executed for each fixture, now they are
    aggregated in a single bulk insert command.

    Lázaro Nixon

  • PostgreSQLAdapter: Allow disable_extension to be called with schema-qualified name.

    For parity with enable_extension, the disable_extension method can be called with a schema-qualified
    name (e.g. disable_extension "myschema.pgcrypto"). Note that PostgreSQL's DROP EXTENSION does not
    actually take a schema name (unlike CREATE EXTENSION), so the resulting SQL statement will only name
    the extension, e.g. DROP EXTENSION IF EXISTS "pgcrypto".

    Tony Novak

  • Make create_schema / drop_schema reversible in migrations.

    Previously, create_schema and drop_schema were irreversible migration operations.

    Tony Novak

  • Support batching using custom columns.

    Product.in_batches(cursor: [:shop_id, :id]) do |relation|
      # do something with relation
    end
    

    fatkodima

  • Use SQLite IMMEDIATE transactions when possible.

    Transactions run against the SQLite3 adapter default to IMMEDIATE mode to improve concurrency support and avoid busy exceptions.

    Stephen Margheim

  • Raise specific exception when a connection is not defined.

    The new ConnectionNotDefined exception provides connection name, shard and role accessors indicating the details of the connection that was requested.

    Hana Harencarova, Matthew Draper

  • Delete the deprecated constant ActiveRecord::ImmutableRelation.

    Xavier Noria

  • Fix duplicate callback execution when child autosaves parent with has_one and belongs_to.

    Before, persisting a new child record with a new associated parent record would run before_validation,
    after_validation, before_save and after_save callbacks twice.

    Now, these callbacks are only executed once as expected.

    Joshua Young

  • ActiveRecord::Encryption::Encryptor now supports a :compressor option to customize the compression algorithm used.

    module ZstdCompressor
      def self.deflate(data)
        Zstd.compress(data)
      end
    
      def self.inflate(data)
        Zstd.decompress(data)
      end
    end
    
    class User
      encrypts :name, compressor: ZstdCompressor
    end
    

    You disable compression by passing compress: false.

    class User
      encrypts :name, compress: false
    end
    

    heka1024

  • Add condensed #inspect for ConnectionPool, AbstractAdapter, and
    DatabaseConfig.

    Hartley McGuire

  • Add .shard_keys, .sharded?, & .connected_to_all_shards methods.

    class ShardedBase < ActiveRecord::Base
        self.abstract_class = true
    
        connects_to shards: {
          shard_one: { writing: :shard_one },
          shard_two: { writing: :shard_two }
        }
    end
    
    class ShardedModel < ShardedBase
    end
    
    ShardedModel.shard_keys => [:shard_one, :shard_two]
    ShardedModel.sharded? => true
    ShardedBase.connected_to_all_shards { ShardedModel.current_shard } => [:shard_one, :shard_two]
    

    Nony Dutton

  • Add a filter option to in_order_of to prioritize certain values in the sorting without filtering the results
    by these values.

    Igor Depolli

  • Fix an issue where the IDs reader method did not return expected results
    for preloaded associations in models using composite primary keys.

    Jay Ang

  • Allow to configure strict_loading_mode globally or within a model.

    Defaults to :all, can be changed to :n_plus_one_only.

    Garen Torikian

  • Add ActiveRecord::Relation#readonly?.

    Reflects if the relation has been marked as readonly.

    Theodor Tonum

  • Improve ActiveRecord::Store to raise a descriptive exception if the column is not either
    structured (e.g., PostgreSQL +hstore+/+json+, or MySQL +json+) or declared serializable via
    ActiveRecord.store.

    Previously, a NoMethodError would be raised when the accessor was read or written:

    NoMethodError: undefined method `accessor' for an instance of ActiveRecord::Type::Text
    

    Now, a descriptive ConfigurationError is raised:

    ActiveRecord::ConfigurationError: the column 'metadata' has not been configured as a store.
      Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your
      database supports it, use a structured column type like hstore or json.
    

    Mike Dalessio

  • Fix inference of association model on nested models with the same demodularized name.

    E.g. with the following setup:

    class Nested::Post < ApplicationRecord
      has_one :post, through: :other
    end
    

    Before, #post would infer the model as Nested::Post, but now it correctly infers Post.

    Joshua Young

  • Add public method for checking if a table is ignored by the schema cache.

    Previously, an application would need to reimplement ignored_table? from the schema cache class to check if a table was set to be ignored. This adds a public method to support this and updates the schema cache to use that directly.

    ActiveRecord.schema_cache_ignored_tables = ["developers"]
    ActiveRecord.schema_cache_ignored_table?("developers")
    => true
    

    Eileen M. Uchitelle

Action View

  • Remove deprecated support to passing a content to void tag elements on the tag builder.

    Rafael Mendonça França

  • Remove deprecated support to passing nil to the model: argument of form_with.

    Rafael Mendonça França

  • Enable DependencyTracker to evaluate renders with trailing interpolation.

    <%= render "maintenance_tasks/runs/info/#{run.status}" %>
    

    Previously, the DependencyTracker would ignore this render, but now it will
    mark all partials in the "maintenance_tasks/runs/info" folder as
    dependencies.

    Hartley McGuire

  • Rename text_area methods into textarea

    Old names are still available as aliases.

    Sean Doyle

  • Rename check_box* methods into checkbox*.

    Old names are still available as aliases.

    Jean Boussier

Action Pack

  • Fix routes with :: in the path.

    Rafael Mendonça França

  • Maintain Rack 2 parameter parsing behaviour.

    Matthew Draper

  • Remove Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality.

    Rafael Mendonça França

  • Improve ActionController::TestCase to expose a binary encoded request.body.

    The rack spec clearly states:

    The input stream is an IO-like object which contains the raw HTTP POST data.
    When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode.

    Until now its encoding was generally UTF-8, which doesn't accurately reflect production
    behavior.

    Jean Boussier

  • Update ActionController::AllowBrowser to support passing method names to :block

    class ApplicationController < ActionController::Base
      allow_browser versions: :modern, block: :handle_outdated_browser
    
      private
        def handle_outdated_browser
          render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
        end
    end
    

    Sean Doyle

  • Raise an ArgumentError when invalid :only or :except options are passed into #resource and #resources.

    Joshua Young

  • Fix non-GET requests not updating cookies in ActionController::TestCase.

    Jon Moss, Hartley McGuire

  • Update ActionController::Live to use a thread-pool to reuse threads across requests.

    Adam Renberg Tamm

  • Introduce safer, more explicit params handling method with params#expect such that
    params.expect(table: [ :attr ]) replaces params.require(:table).permit(:attr)

    Ensures params are filtered with consideration for the expected
    types of values, improving handling of params and avoiding ignorable
    errors caused by params tampering.

    # If the url is altered to ?person=hacked
    # Before
    params.require(:person).permit(:name, :age, pets: [:name])
    # raises NoMethodError, causing a 500 and potential error reporting
    
    # After
    params.expect(person: [ :name, :age, pets: [[:name]] ])
    # raises ActionController::ParameterMissing, correctly returning a 400 error
    

    You may also notice the new double array [[:name]]. In order to
    declare when a param is expected to be an array of parameter hashes,
    this new double array syntax is used to explicitly declare an array.
    expect requires you to declare expected arrays in this way, and will
    ignore arrays that are passed when, for example, pet: [:name] is used.

    In order to preserve compatibility, permit does not adopt the new
    double array syntax and is therefore more permissive about unexpected
    types. Using expect everywhere is recommended.

    We suggest replacing params.require(:person).permit(:name, :age)
    with the direct replacement params.expect(person: [:name, :age])
    to prevent external users from manipulating params to trigger 500
    errors. A 400 error will be returned instead, using public/400.html

    Usage of params.require(:id) should likewise be replaced with
    params.expect(:id) which is designed to ensure that params[:id]
    is a scalar and not an array or hash, also requiring the param.

    # Before
    User.find(params.require(:id)) # allows an array, altering behavior
    
    # After
    User.find(params.expect(:id)) # expect only returns non-blank permitted scalars (excludes Hash, Array, nil, "", etc)
    

    Martin Emde

  • System Testing: Disable Chrome's search engine choice by default in system tests.

    glaszig

  • Fix Request#raw_post raising NoMethodError when rack.input is nil.

    Hartley McGuire

  • Remove racc dependency by manually writing ActionDispatch::Journey::Scanner.

    Gannon McGibbon

  • Speed up ActionDispatch::Routing::Mapper::Scope#[] by merging frame hashes.

    Gannon McGibbon

  • Allow bots to ignore allow_browser.

    Matthew Nguyen

  • Deprecate drawing routes with multiple paths to make routing faster.
    You may use with_options or a loop to make drawing multiple paths easier.

    # Before
    get "/users", "/other_path", to: "users#index"
    
    # After
    get "/users", to: "users#index"
    get "/other_path", to: "users#index"
    

    Gannon McGibbon

  • Make http_cache_forever use immutable: true

    Nate Matykiewicz

  • Add config.action_dispatch.strict_freshness.

    When set to true, the ETag header takes precedence over the Last-Modified header when both are present,
    as specified by RFC 7232, Section 6.

    Defaults to false to maintain compatibility with previous versions of Rails, but is enabled as part of
    Rails 8.0 defaults.

    heka1024

  • Support immutable directive in Cache-Control

    expires_in 1.minute, public: true, immutable: true
    # Cache-Control: public, max-age=60, immutable
    

    heka1024

  • Add :wasm_unsafe_eval mapping for content_security_policy

    # Before
    policy.script_src "'wasm-unsafe-eval'"
    
    # After
    policy.script_src :wasm_unsafe_eval
    

    Joe Haig

  • Add display_capture and keyboard_map in permissions_policy

    Cyril Blaecke

  • Add connect route helper.

    Samuel Williams

Active Job

  • Remove deprecated config.active_job.use_big_decimal_serializer.

    Rafael Mendonça França

  • Deprecate sucker_punch as an adapter option.

    If you're using this adapter, change to adapter: async for the same functionality.

    Dino Maric, zzak

  • Use RAILS_MAX_THREADS in ActiveJob::AsyncAdapter. If it is not set, use 5 as default.

    heka1024

Action Mailer

  • No changes.

Action Cable

  • Add an identifier to the event payload for the ActiveSupport::Notification transmit_subscription_confirmation.action_cable and transmit_subscription_rejection.action_cable.

    Keith Schacht

Active Storage

  • Deprecate ActiveStorage::Service::AzureStorageService.

    zzak

  • Improve ActiveStorage::Filename#sanitized method to handle special characters more effectively.
    Replace the characters "*?<> with - if they exist in the Filename to match the Filename convention of Win OS.

    Luong Viet Dung(Martin)

  • Improve InvariableError, UnpreviewableError and UnrepresentableError message.

    Include Blob ID and content_type in the messages.

    Petrik de Heus

  • Mark proxied files as immutable in their Cache-Control header

    Nate Matykiewicz

Action Mailbox

  • No changes.

Action Text

  • Dispatch direct-upload events on attachment uploads

    When using Action Text's rich textarea, it's possible to attach files to the
    editor. Previously, that action didn't dispatch any events, which made it hard
    to react to the file uploads. For instance, if an upload failed, there was no
    way to notify the user about it, or remove the attachment from the editor.

    This commits adds new events - direct-upload:start, direct-upload:progress,
    and direct-upload:end - similar to how Active Storage's direct uploads work.

    Matheus Richard, Brad Rees

  • Add store_if_blank option to has_rich_text

    Pass store_if_blank: false to not create ActionText::RichText records when saving with a blank attribute, such as from an optional form parameter.

    class Message
      has_rich_text :content, store_if_blank: false
    end
    
    Message.create(content: "hi") # creates an ActionText::RichText
    Message.create(content: "") # does not create an ActionText::RichText
    

    Alex Ghiculescu

  • Strip content attribute if the key is present but the value is empty

    Jeremy Green

  • Rename rich_text_area methods into rich_textarea

    Old names are still available as aliases.

    Sean Doyle

  • Only sanitize content attribute when present in attachments.

    Petrik de Heus

Railties

  • Fix incorrect database.yml with skip_solid.

    Joé Dupuis

  • Set Regexp.timeout to 1s by default to improve security over Regexp Denial-of-Service attacks.

    Rafael Mendonça França

  • Remove deprecated support to extend Rails console through Rails::ConsoleMethods.

    Rafael Mendonça França

  • Remove deprecated file rails/console/helpers.

    Rafael Mendonça França

  • Remove deprecated file rails/console/app.

    Rafael Mendonça França

  • Remove deprecated config.read_encrypted_secrets.

    Rafael Mendonça França

  • Add Kamal support for devcontainers

    Previously generated devcontainer could not use docker and therefore Kamal.

    Joé Dupuis

  • Exit rails g with code 1 if generator could not be found.

    Previously rails g returned 0, which would make it harder to catch typos in scripts calling rails g.

    Christopher Özbek

  • Remove require_* statements from application.css to align with the transition from Sprockets to Propshaft.

    With Propshaft as the default asset pipeline in Rails 8, the require_tree and require_self clauses in application.css are no longer necessary, as they were specific to Sprockets. Additionally, the comment has been updated to clarify that CSS precedence now follows standard cascading order without automatic prioritization by the asset pipeline.

    Eduardo Alencar

  • Do not include redis by default in generated Dev Containers.

    Now that applications use the Solid Queue and Solid Cache gems by default, we do not need to include redis
    in the Dev Container. We will only include redis if --skip-solid is used when generating an app that uses
    Active Job or Action Cable.

    When generating a Dev Container for an existing app, we will not include redis if either of the solid gems
    are in use.

    Andrew Novoselac

  • Use Solid Cable as the default Action Cable adapter in production, configured as a separate queue database in config/database.yml. It keeps messages in a table and continuously polls for updates. This makes it possible to drop the common dependency on Redis, if it isn't needed for any other purpose. Despite polling, the performance of Solid Cable is comparable to Redis in most situations. And in all circumstances, it makes it easier to deploy Rails when Redis is no longer a required dependency for Action Cable functionality.

    DHH

  • Use Solid Queue as the default Active Job backend in production, configured as a separate queue database in config/database.yml. In a single-server deployment, it'll run as a Puma plugin. This is configured in config/deploy.yml and can easily be changed to use a dedicated jobs machine.

    DHH

  • Use Solid Cache as the default Rails.cache backend in production, configured as a separate cache database in config/database.yml.

    DHH

  • Add Rails::Rack::SilenceRequest middleware and use it via config.silence_healthcheck_path = path
    to silence requests to "/up". This prevents the Kamal-required health checks from clogging up
    the production logs.

    DHH

  • Introduce mariadb-mysql and mariadb-trilogy database options for rails new

    When used with the --devcontainer flag, these options will use mariadb as the database for the
    Dev Container. The original mysql and trilogy options will use mysql. Users who are not
    generating a Dev Container do not need to use the new options.

    Andrew Novoselac

  • Deprecate ::STATS_DIRECTORIES.

    The global constant STATS_DIRECTORIES has been deprecated in favor of
    Rails::CodeStatistics.register_directory.

    Add extra directories with Rails::CodeStatistics.register_directory(label, path):

    require "rails/code_statistics"
    Rails::CodeStatistics.register_directory('My Directory', 'path/to/dir')
    

    Petrik de Heus

  • Enable query log tags by default on development env

    This can be used to trace troublesome SQL statements back to the application
    code that generated these statements. It is also useful when using multiple
    databases because the query logs can identify which database is being used.

    Matheus Richard

  • Defer route drawing to the first request, or when url_helpers are called

    Executes the first routes reload in middleware, or when a route set's
    url_helpers receives a route call / asked if it responds to a route.
    Previously, this was executed unconditionally on boot, which can
    slow down boot time unnecessarily for larger apps with lots of routes.

    Environments like production that have config.eager_load = true will
    continue to eagerly load routes on boot.

    Gannon McGibbon

  • Generate form helpers to use textarea* methods instead of text_area* methods

    Sean Doyle

  • Add authentication generator to give a basic start to an authentication system using database-tracked sessions and password reset.

    Generate with...

    bin/rails generate authentication
    

    Generated files:

    app/models/current.rb
    app/models/user.rb
    app/models/session.rb
    app/controllers/sessions_controller.rb
    app/controllers/passwords_controller.rb
    app/mailers/passwords_mailer.rb
    app/views/sessions/new.html.erb
    app/views/passwords/new.html.erb
    app/views/passwords/edit.html.erb
    app/views/passwords_mailer/reset.html.erb
    app/views/passwords_mailer/reset.text.erb
    db/migrate/xxxxxxx_create_users.rb
    db/migrate/xxxxxxx_create_sessions.rb
    test/mailers/previews/passwords_mailer_preview.rb
    

    DHH

  • Add not-null type modifier to migration attributes.

    Generating with...

    bin/rails generate migration CreateUsers email_address:string!:uniq password_digest:string!
    

    Produces:

    class CreateUsers < ActiveRecord::Migration[8.0]
      def change
        create_table :users do |t|
          t.string :email_address, null: false
          t.string :password_digest, null: false
    
          t.timestamps
        end
        add_index :users, :email_address, unique: true
      end
    end
    

    DHH

  • Add a script folder to applications, and a scripts generator.

    The new script folder is meant to hold one-off or general purpose scripts,
    such as data migration scripts, cleanup scripts, etc.

    A new script generator allows you to create such scripts:

    bin/rails generate script my_script
    bin/rails generate script data/backfill
    

    You can run the generated script using:

    bundle exec ruby script/my_script.rb
    bundle exec ruby script/data/backfill.rb
    

    Jerome Dalbert, Haroon Ahmed

  • Deprecate bin/rake stats in favor of bin/rails stats.

    Juan Vásquez

  • Add internal page /rails/info/notes, that displays the same information as bin/rails notes.

    Deepak Mahakale

  • Add Rubocop and GitHub Actions to plugin generator.
    This can be skipped using --skip-rubocop and --skip-ci.

    Chris Oliver

  • Use Kamal for deployment by default, which includes generating a Rails-specific config/deploy.yml.
    This can be skipped using --skip-kamal. See more: https://kamal-deploy.org/

    DHH

Guides

  • The guide Classic to Zeitwerk HOWTO that documented how to migrate from
    the classic autoloader to Zeitwerk has been deleted.

    The last version of this guide can be found
    here,
    in case you need it.

    Petrik de Heus

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.2

Active Support

  • Include options when instrumenting ActiveSupport::Cache::Store#delete and ActiveSupport::Cache::Store#delete_multi.

    Adam Renberg Tamm

  • Print test names when running rails test -v for parallel tests.

    John Hawthorn, Abeid Ahmed

Active Model

  • Fix regression in alias_attribute to work with user defined methods.

    alias_attribute would wrongly assume the attribute accessor was generated by Active Model.

    class Person
      include ActiveModel::AttributeMethods
    
      define_attribute_methods :name
      attr_accessor :name
    
      alias_attribute :full_name, :name
    end
    
    person.full_name # => NoMethodError: undefined method `attribute' for an instance of Person
    

    Jean Boussier

Active Record

  • Fix support for query_cache: false in database.yml.

    query_cache: false would no longer entirely disable the Active Record query cache.

    zzak

  • Set .attributes_for_inspect to :all by default.

    For new applications it is set to [:id] in config/environment/production.rb.

    In the console all the attributes are always shown.

    Andrew Novoselac

  • PG::UnableToSend: no connection to the server is now retryable as a connection-related exception

    Kazuma Watanabe

  • Fix marshalling of unsaved associated records in 7.1 format.

    The 7.1 format would only marshal associated records if the association was loaded.
    But associations that would only contain unsaved records would be skipped.

    Jean Boussier

  • Fix incorrect SQL query when passing an empty hash to ActiveRecord::Base.insert.

    David Stosik

  • Allow to save records with polymorphic join tables that have inverse_of
    specified.

    Markus Doits

  • Fix association scopes applying on the incorrect join when using a polymorphic has_many through:.

    Joshua Young

  • Fix dependent: :destroy for bi-directional has one through association.

    Fixes #50948.

    class Left < ActiveRecord::Base
      has_one :middle, dependent: :destroy
      has_one :right, through: :middle
    end
    
    class Middle < ActiveRecord::Base
      belongs_to :left, dependent: :destroy
      belongs_to :right, dependent: :destroy
    end
    
    class Right < ActiveRecord::Base
      has_one :middle, dependent: :destroy
      has_one :left, through: :middle
    end
    

    In the above example left.destroy wouldn't destroy its associated Right
    record.

    Andy Stewart

  • Properly handle lazily pinned connection pools.

    Fixes #53147.

    When using transactional fixtures with system tests to similar tools
    such as capybara, it could happen that a connection end up pinned by the
    server thread rather than the test thread, causing
    "Cannot expire connection, it is owned by a different thread" errors.

    Jean Boussier

  • Fix ActiveRecord::Base.with to accept more than two sub queries.

    Fixes #53110.

    User.with(foo: [User.select(:id), User.select(:id), User.select(:id)]).to_sql
    undefined method `union' for an instance of Arel::Nodes::UnionAll (NoMethodError)
    

    The above now works as expected.

    fatkodima

  • Properly release pinned connections with non joinable connections.

    Fixes #52973

    When running system tests with transactional fixtures on, it could happen that
    the connection leased by the Puma thread wouldn't be properly released back to the pool,
    causing "Cannot expire connection, it is owned by a different thread" errors in later tests.

    Jean Boussier

  • Make Float distinguish between float4 and float8 in PostgreSQL.

    Fixes #52742

    Ryota Kitazawa, Takayuki Nagatomi

  • Fix an issue where .left_outer_joins used with multiple associations that have
    the same child association but different parents does not join all parents.

    Previously, using .left_outer_joins with the same child association would only join one of the parents.

    Now it will correctly join both parents.

    Fixes #41498.

    Garrett Blehm

  • Ensure ActiveRecord::Encryption.config is always ready before access.

    Previously, ActiveRecord::Encryption configuration was deferred until ActiveRecord::Base
    was loaded. Therefore, accessing ActiveRecord::Encryption.config properties before
    ActiveRecord::Base was loaded would give incorrect results.

    ActiveRecord::Encryption now has its own loading hook so that its configuration is set as
    soon as needed.

    When ActiveRecord::Base is loaded, even lazily, it in turn triggers the loading of
    ActiveRecord::Encryption, thus preserving the original behavior of having its config ready
    before any use of ActiveRecord::Base.

    Maxime Réty

  • Add TimeZoneConverter#== method, so objects will be properly compared by
    their type, scale, limit & precision.

    Address #52699.

    Ruy Rocha

Action View

  • No changes.

Action Pack

  • Fix non-GET requests not updating cookies in ActionController::TestCase.

    Jon Moss, Hartley McGuire

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.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.1.5

Active Support

  • No changes.

Active Model

  • Fix regression in alias_attribute to work with user defined methods.

    alias_attribute would wrongly assume the attribute accessor was generated by Active Model.

    class Person
      include ActiveModel::AttributeMethods
    
      define_attribute_methods :name
      attr_accessor :name
    
      alias_attribute :full_name, :name
    end
    
    person.full_name # => NoMethodError: undefined method `attribute' for an instance of Person
    

    Jean Boussier

Active Record

  • Fix marshalling of unsaved associated records in 7.1 format.

    The 7.1 format would only marshal associated records if the association was loaded.
    But associations that would only contain unsaved records would be skipped.

    Jean Boussier

  • Fix an issue where .left_outer_joins used with multiple associations that have
    the same child association but different parents does not join all parents.

    Previously, using .left_outer_joins with the same child association would only join one of the parents.

    Now it will correctly join both parents.

    Fixes #41498.

    Garrett Blehm

  • Ensure ActiveRecord::Encryption.config is always ready before access.

    Previously, ActiveRecord::Encryption configuration was deferred until ActiveRecord::Base
    was loaded. Therefore, accessing ActiveRecord::Encryption.config properties before
    ActiveRecord::Base was loaded would give incorrect results.

    ActiveRecord::Encryption now has its own loading hook so that its configuration is set as
    soon as needed.

    When ActiveRecord::Base is loaded, even lazily, it in turn triggers the loading of
    ActiveRecord::Encryption, thus preserving the original behavior of having its config ready
    before any use of ActiveRecord::Base.

    Maxime Réty

  • Add TimeZoneConverter#== method, so objects will be properly compared by
    their type, scale, limit & precision.

    Address #52699.

    Ruy Rocha

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 8.0.0.rc2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • NULLS NOT DISTINCT works with UNIQUE CONSTRAINT as well as UNIQUE INDEX.

    Ryuta Kamizono

  • The db:prepare task no longer loads seeds when a non-primary database is created.

    Previously, the db:prepare task would load seeds whenever a new database
    is created, leading to potential loss of data if a database is added to an
    existing environment.

    Introduces a new database config property seeds to control whether seeds
    are loaded during db:prepare which defaults to true for primary database
    configs and false otherwise.

    Fixes #53348.

    Mike Dalessio

  • PG::UnableToSend: no connection to the server is now retryable as a connection-related exception

    Kazuma Watanabe

  • Fix strict loading propagation even if statement cache is not used.

    Ryuta Kamizono

  • Allow rename_enum accepts two from/to name arguments as rename_table does so.

    Ryuta Kamizono

Action View

  • No changes.

Action Pack

  • Fix routes with :: in the path.

    Rafael Mendonça França

  • Maintain Rack 2 parameter parsing behaviour.

    Matthew Draper

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

  • Fix incorrect database.yml with skip_solid.

    Joé Dupuis

  • Set Regexp.timeout to 1s by default to improve security over Regexp Denial-of-Service attacks.

    Rafael Mendonça França

Guides

  • No changes.

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.1.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • Fix NoMethodError in block_format helper

    Michael Leimstaedtner

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.1.4.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • Fix NoMethodError in block_format helper

    Michael Leimstaedtner

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.0.8.6

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • Fix NoMethodError in block_format helper

    Michael Leimstaedtner

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 6.1.7.10

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • Fix NoMethodError in block_format helper

    Michael Leimstaedtner

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 8.0.0.rc1

Active Support

  • Remove deprecated support to passing an array of strings to ActiveSupport::Deprecation#warn.

    Rafael Mendonça França

  • Remove deprecated support to setting attr_internal_naming_format with a @ prefix.

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::ProxyObject.

    Rafael Mendonça França

  • Don't execute i18n watcher on boot. It shouldn't catch any file changes initially,
    and unnecessarily slows down boot of applications with lots of translations.

    Gannon McGibbon, David Stosik

  • Fix ActiveSupport::HashWithIndifferentAccess#stringify_keys to stringify all keys not just symbols.

    Previously:

    { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
    

    After this change:

    { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
    

    This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
    to not backport the fix and to make the change in a major release.

    Jean Boussier

Active Model

  • Add :except_on option for validations. Grants the ability to skip validations in specified contexts.

    class User < ApplicationRecord
        #...
        validates :birthday, presence: { except_on: :admin }
        #...
    end
    
    user = User.new(attributes except birthday)
    user.save(context: :admin)
    

    Drew Bragg

Active Record

  • Remove deprecated support to setting ENV["SCHEMA_CACHE"].

    Rafael Mendonça França

  • Remove deprecated support to passing a database name to cache_dump_filename.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::ConnectionPool#connection.

    Rafael Mendonça França

  • Remove deprecated config.active_record.sqlite3_deprecated_warning.

    Rafael Mendonça França

  • Remove deprecated config.active_record.warn_on_records_fetched_greater_than.

    Rafael Mendonça França

  • Remove deprecated support for defining enum with keyword arguments.

    Rafael Mendonça França

  • Remove deprecated support to finding database adapters that aren't registered to Active Record.

    Rafael Mendonça França

  • Remove deprecated config.active_record.allow_deprecated_singular_associations_name.

    Rafael Mendonça França

  • Remove deprecated config.active_record.commit_transaction_on_non_local_return.

    Rafael Mendonça França

  • Fix incorrect SQL query when passing an empty hash to ActiveRecord::Base.insert.

    David Stosik

  • Allow to save records with polymorphic join tables that have inverse_of
    specified.

    Markus Doits

  • Fix association scopes applying on the incorrect join when using a polymorphic has_many through:.

    Joshua Young

  • Allow ActiveRecord::Base#pluck to accept hash arguments with symbol and string values.

    Post.joins(:comments).pluck(:id, comments: :id)
    Post.joins(:comments).pluck("id", "comments" => "id")
    

    Joshua Young

  • Make Float distinguish between float4 and float8 in PostgreSQL.

    Fixes #52742

    Ryota Kitazawa, Takayuki Nagatomi

Action View

  • Remove deprecated support to passing a content to void tag elements on the tag builder.

    Rafael Mendonça França

  • Remove deprecated support to passing nil to the model: argument of form_with.

    Rafael Mendonça França

Action Pack

  • Remove Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality.

    Rafael Mendonça França

  • Improve ActionController::TestCase to expose a binary encoded request.body.

    The rack spec clearly states:

    The input stream is an IO-like object which contains the raw HTTP POST data.
    When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode.

    Until now its encoding was generally UTF-8, which doesn't accurately reflect production
    behavior.

    Jean Boussier

  • Update ActionController::AllowBrowser to support passing method names to :block

    class ApplicationController < ActionController::Base
      allow_browser versions: :modern, block: :handle_outdated_browser
    
      private
        def handle_outdated_browser
          render file: Rails.root.join("public/custom-error.html"), status: :not_acceptable
        end
    end
    

    Sean Doyle

  • Raise an ArgumentError when invalid :only or :except options are passed into #resource and #resources.

    Joshua Young

Active Job

  • Remove deprecated config.active_job.use_big_decimal_serializer.

    Rafael Mendonça França

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Remove deprecated support to extend Rails console through Rails::ConsoleMethods.

    Rafael Mendonça França

  • Remove deprecated file rails/console/helpers.

    Rafael Mendonça França

  • Remove deprecated file rails/console/app.

    Rafael Mendonça França

  • Remove deprecated config.read_encrypted_secrets.

    Rafael Mendonça França

  • Add Kamal support for devcontainers

    Previously generated devcontainer could not use docker and therefore Kamal.

    Joé Dupuis

Guides

  • No changes.

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 6.1.7.9

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Avoid regex backtracking in HTTP Token authentication

    [CVE-2024-47887]

  • Avoid regex backtracking in query parameter filtering

    [CVE-2024-41128]

Active Job

  • No changes.

Action Mailer

  • Avoid regex backtracking in block_format helper

    [CVE-2024-47889]

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Avoid backtracing in plain_text_for_blockquote_node

    [CVE-2024-47888]

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.1.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Avoid regex backtracking in HTTP Token authentication

    [CVE-2024-47887]

  • Avoid regex backtracking in query parameter filtering

    [CVE-2024-41128]

Active Job

  • No changes.

Action Mailer

  • Avoid regex backtracking in block_format helper

    [CVE-2024-47889]

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Avoid backtracing in plain_text_for_blockquote_node

    [CVE-2024-47888]

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.1.4.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Avoid regex backtracking in HTTP Token authentication

    [CVE-2024-47887]

  • Avoid regex backtracking in query parameter filtering

    [CVE-2024-41128]

Active Job

  • No changes.

Action Mailer

  • Avoid regex backtracking in block_format helper

    [CVE-2024-47889]

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Avoid backtracing in plain_text_for_blockquote_node

    [CVE-2024-47888]

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.0.8.5

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Avoid regex backtracking in HTTP Token authentication

    [CVE-2024-47887]

  • Avoid regex backtracking in query parameter filtering

    [CVE-2024-41128]

Active Job

  • No changes.

Action Mailer

  • Avoid regex backtracking in block_format helper

    [CVE-2024-47889]

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Avoid backtracing in plain_text_for_blockquote_node

    [CVE-2024-47888]

Railties

  • No changes.

Guides

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 8.0.0.beta1

Active Support

  • Include options when instrumenting ActiveSupport::Cache::Store#delete and ActiveSupport::Cache::Store#delete_multi.

    Adam Renberg Tamm

  • Print test names when running rails test -v for parallel tests.

    John Hawthorn, Abeid Ahmed

  • Deprecate Benchmark.ms core extension.

    The benchmark gem will become bundled in Ruby 3.5

    Earlopain

  • ActiveSupport::TimeWithZone#inspect now uses ISO 8601 style time like Time#inspect

    John Hawthorn

  • ActiveSupport::ErrorReporter#report now assigns a backtrace to unraised exceptions.

    Previously reporting an un-raised exception would result in an error report without
    a backtrace. Now it automatically generates one.

    Jean Boussier

  • Add escape_html_entities option to ActiveSupport::JSON.encode.

    This allows for overriding the global configuration found at
    ActiveSupport.escape_html_entities_in_json for specific calls to to_json.

    This should be usable from controllers in the following manner:

    class MyController < ApplicationController
      def index
        render json: { hello: "world" }, escape_html_entities: false
      end
    end
    

    Nigel Baillie

  • Raise when using key which can't respond to #to_sym in EncryptedConfiguration.

    As is the case when trying to use an Integer or Float as a key, which is unsupported.

    zzak

  • Deprecate addition and since between two Time and ActiveSupport::TimeWithZone.

    Previously adding time instances together such as 10.days.ago + 10.days.ago or 10.days.ago.since(10.days.ago) produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.

    Nick Schwaderer

  • Support rfc2822 format for Time#to_fs & Date#to_fs.

    Akshay Birajdar

  • Optimize load time for Railtie#initialize_i18n. Filter I18n.load_paths passed to the file watcher to only those
    under Rails.root. Previously the watcher would grab all available locales, including those in gems
    which do not require a watcher because they won't change.

    Nick Schwaderer

  • Add a filter option to in_order_of to prioritize certain values in the sorting without filtering the results
    by these values.

    Igor Depolli

  • Improve error message when using assert_difference or assert_changes with a
    proc by printing the proc's source code (MRI only).

    Richard Böhme, Jean Boussier

  • Add a new configuration value :zone for ActiveSupport.to_time_preserves_timezone and rename the previous true value to :offset. The new default value is :zone.

    Jason Kim, John Hawthorn

  • Align instrumentation payload[:key] in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys.

    Frederik Erbs Spang Thomsen

  • Fix travel_to to set usec 0 when with_usec is false and the given argument String or DateTime.

    mopp

Active Model

  • Make ActiveModel::Serialization#read_attribute_for_serialization public

    Sean Doyle

  • Add a default token generator for password reset tokens when using has_secure_password.

    class User < ApplicationRecord
      has_secure_password
    end
    
    user = User.create!(name: "david", password: "123", password_confirmation: "123")
    token = user.password_reset_token
    User.find_by_password_reset_token(token) # returns user
    
    # 16 minutes later...
    User.find_by_password_reset_token(token) # returns nil
    
    # raises ActiveSupport::MessageVerifier::InvalidSignature since the token is expired
    User.find_by_password_reset_token!(token)
    

    DHH

  • Add a load hook active_model_translation for ActiveModel::Translation.

    Shouichi Kamiya

  • Add raise_on_missing_translations option to ActiveModel::Translation.
    When the option is set, human_attribute_name raises an error if a translation of the given attribute is missing.

    # ActiveModel::Translation.raise_on_missing_translations = false
    Post.human_attribute_name("title")
    => "Title"
    
    # ActiveModel::Translation.raise_on_missing_translations = true
    Post.human_attribute_name("title")
    => Translation missing. Options considered were: (I18n::MissingTranslationData)
        - en.activerecord.attributes.post.title
        - en.attributes.title
    
                raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Shouichi Kamiya

  • Introduce ActiveModel::AttributeAssignment#attribute_writer_missing

    Provide instances with an opportunity to gracefully handle assigning to an
    unknown attribute:

    class Rectangle
      include ActiveModel::AttributeAssignment
    
      attr_accessor :length, :width
    
      def attribute_writer_missing(name, value)
        Rails.logger.warn "Tried to assign to unknown attribute #{name}"
      end
    end
    
    rectangle = Rectangle.new
    rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
    

    Sean Doyle

Active Record

  • Allow drop_table to accept an array of table names.

    This will let you to drop multiple tables in a single call.

    ActiveRecord::Base.lease_connection.drop_table(:users, :posts)
    

    Gabriel Sobrinho

  • Add support for PostgreSQL IF NOT EXISTS via the :if_not_exists option
    on the add_enum_value method.

    Ariel Rzezak

  • When running db:migrate on a fresh database, load the database schema before running migrations.

    Andrew Novoselac

  • Fix an issue where .left_outer_joins used with multiple associations that have
    the same child association but different parents does not join all parents.

    Previously, using .left_outer_joins with the same child association would only join one of the parents.

    Now it will correctly join both parents.

    Fixes #41498.

    Garrett Blehm

  • Deprecate unsigned_float and unsigned_decimal short-hand column methods.

    As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE,
    and DECIMAL. Consider using a simple CHECK constraint instead for such columns.

    https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html

    Ryuta Kamizono

  • Drop MySQL 5.5 support.

    MySQL 5.5 is the only version that does not support datetime with precision,
    which we have supported in the core. Now we support MySQL 5.6.4 or later, which
    is the first version to support datetime with precision.

    Ryuta Kamizono

  • Make Active Record asynchronous queries compatible with transactional fixtures.

    Previously transactional fixtures would disable asynchronous queries, because transactional
    fixtures impose all queries use the same connection.

    Now asynchronous queries will use the connection pinned by transactional fixtures, and behave
    much closer to production.

    Jean Boussier

  • Deserialize binary data before decrypting

    This ensures that we call PG::Connection.unescape_bytea on PostgreSQL before decryption.

    Donal McBreen

  • Ensure ActiveRecord::Encryption.config is always ready before access.

    Previously, ActiveRecord::Encryption configuration was deferred until ActiveRecord::Base
    was loaded. Therefore, accessing ActiveRecord::Encryption.config properties before
    ActiveRecord::Base was loaded would give incorrect results.

    ActiveRecord::Encryption now has its own loading hook so that its configuration is set as
    soon as needed.

    When ActiveRecord::Base is loaded, even lazily, it in turn triggers the loading of
    ActiveRecord::Encryption, thus preserving the original behavior of having its config ready
    before any use of ActiveRecord::Base.

    Maxime Réty

  • Add TimeZoneConverter#== method, so objects will be properly compared by
    their type, scale, limit & precision.

    Address #52699.

    Ruy Rocha

  • Add support for SQLite3 full-text-search and other virtual tables.

    Previously, adding sqlite3 virtual tables messed up schema.rb.

    Now, virtual tables can safely be added using create_virtual_table.

    Zacharias Knudsen

  • Support use of alternative database interfaces via the database_cli ActiveRecord configuration option.

    Rails.application.configure do
      config.active_record.database_cli = { postgresql: "pgcli" }
    end
    

    T S Vallender

  • Add support for dumping table inheritance and native partitioning table definitions for PostgeSQL adapter

    Justin Talbott

  • Add support for ActiveRecord::Point type casts using Hash values

    This allows ActiveRecord::Point to be cast or serialized from a hash
    with :x and :y keys of numeric values, mirroring the functionality of
    existing casts for string and array values. Both string and symbol keys are
    supported.

    class PostgresqlPoint < ActiveRecord::Base
      attribute :x, :point
      attribute :y, :point
      attribute :z, :point
    end
    
    val = PostgresqlPoint.new({
      x: '(12.34, -43.21)',
      y: [12.34, '-43.21'],
      z: {x: '12.34', y: -43.21}
    })
    ActiveRecord::Point.new(12.32, -43.21) == val.x == val.y == val.z
    

    Stephen Drew

  • Replace SQLite3::Database#busy_timeout with #busy_handler_timeout=.

    Provides a non-GVL-blocking, fair retry interval busy handler implementation.

    Stephen Margheim

  • SQLite3Adapter: Translate SQLite3::BusyException into ActiveRecord::StatementTimeout.

    Matthew Nguyen

  • Include schema name in enable_extension statements in db/schema.rb.

    The schema dumper will now include the schema name in generated
    enable_extension statements if they differ from the current schema.

    For example, if you have a migration:

    enable_extension "heroku_ext.pgcrypto"
    enable_extension "pg_stat_statements"
    

    then the generated schema dump will also contain:

    enable_extension "heroku_ext.pgcrypto"
    enable_extension "pg_stat_statements"
    

    Tony Novak

  • Fix ActiveRecord::Encryption::EncryptedAttributeType#type to return
    actual cast type.

    Vasiliy Ermolovich

  • SQLite3Adapter: Bulk insert fixtures.

    Previously one insert command was executed for each fixture, now they are
    aggregated in a single bulk insert command.

    Lázaro Nixon

  • PostgreSQLAdapter: Allow disable_extension to be called with schema-qualified name.

    For parity with enable_extension, the disable_extension method can be called with a schema-qualified
    name (e.g. disable_extension "myschema.pgcrypto"). Note that PostgreSQL's DROP EXTENSION does not
    actually take a schema name (unlike CREATE EXTENSION), so the resulting SQL statement will only name
    the extension, e.g. DROP EXTENSION IF EXISTS "pgcrypto".

    Tony Novak

  • Make create_schema / drop_schema reversible in migrations.

    Previously, create_schema and drop_schema were irreversible migration operations.

    Tony Novak

  • Support batching using custom columns.

    Product.in_batches(cursor: [:shop_id, :id]) do |relation|
      # do something with relation
    end
    

    fatkodima

  • Use SQLite IMMEDIATE transactions when possible.

    Transactions run against the SQLite3 adapter default to IMMEDIATE mode to improve concurrency support and avoid busy exceptions.

    Stephen Margheim

  • Raise specific exception when a connection is not defined.

    The new ConnectionNotDefined exception provides connection name, shard and role accessors indicating the details of the connection that was requested.

    Hana Harencarova, Matthew Draper

  • Delete the deprecated constant ActiveRecord::ImmutableRelation.

    Xavier Noria

  • Fix duplicate callback execution when child autosaves parent with has_one and belongs_to.

    Before, persisting a new child record with a new associated parent record would run before_validation,
    after_validation, before_save and after_save callbacks twice.

    Now, these callbacks are only executed once as expected.

    Joshua Young

  • ActiveRecord::Encryption::Encryptor now supports a :compressor option to customize the compression algorithm used.

    module ZstdCompressor
      def self.deflate(data)
        Zstd.compress(data)
      end
    
      def self.inflate(data)
        Zstd.decompress(data)
      end
    end
    
    class User
      encrypts :name, compressor: ZstdCompressor
    end
    

    You disable compression by passing compress: false.

    class User
      encrypts :name, compress: false
    end
    

    heka1024

  • Add condensed #inspect for ConnectionPool, AbstractAdapter, and
    DatabaseConfig.

    Hartley McGuire

  • Add .shard_keys, .sharded?, & .connected_to_all_shards methods.

    class ShardedBase < ActiveRecord::Base
        self.abstract_class = true
    
        connects_to shards: {
          shard_one: { writing: :shard_one },
          shard_two: { writing: :shard_two }
        }
    end
    
    class ShardedModel < ShardedBase
    end
    
    ShardedModel.shard_keys => [:shard_one, :shard_two]
    ShardedModel.sharded? => true
    ShardedBase.connected_to_all_shards { ShardedModel.current_shard } => [:shard_one, :shard_two]
    

    Nony Dutton

  • Add a filter option to in_order_of to prioritize certain values in the sorting without filtering the results
    by these values.

    Igor Depolli

  • Fix an issue where the IDs reader method did not return expected results
    for preloaded associations in models using composite primary keys.

    Jay Ang

  • Allow to configure strict_loading_mode globally or within a model.

    Defaults to :all, can be changed to :n_plus_one_only.

    Garen Torikian

  • Add ActiveRecord::Relation#readonly?.

    Reflects if the relation has been marked as readonly.

    Theodor Tonum

  • Improve ActiveRecord::Store to raise a descriptive exception if the column is not either
    structured (e.g., PostgreSQL +hstore+/+json+, or MySQL +json+) or declared serializable via
    ActiveRecord.store.

    Previously, a NoMethodError would be raised when the accessor was read or written:

    NoMethodError: undefined method `accessor' for an instance of ActiveRecord::Type::Text
    

    Now, a descriptive ConfigurationError is raised:

    ActiveRecord::ConfigurationError: the column 'metadata' has not been configured as a store.
      Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your
      database supports it, use a structured column type like hstore or json.
    

    Mike Dalessio

  • Fix inference of association model on nested models with the same demodularized name.

    E.g. with the following setup:

    class Nested::Post < ApplicationRecord
      has_one :post, through: :other
    end
    

    Before, #post would infer the model as Nested::Post, but now it correctly infers Post.

    Joshua Young

  • Add public method for checking if a table is ignored by the schema cache.

    Previously, an application would need to reimplement ignored_table? from the schema cache class to check if a table was set to be ignored. This adds a public method to support this and updates the schema cache to use that directly.

    ActiveRecord.schema_cache_ignored_tables = ["developers"]
    ActiveRecord.schema_cache_ignored_table?("developers")
    => true
    

    Eileen M. Uchitelle

Action View

  • Enable DependencyTracker to evaluate renders with trailing interpolation.

    <%= render "maintenance_tasks/runs/info/#{run.status}" %>
    

    Previously, the DependencyTracker would ignore this render, but now it will
    mark all partials in the "maintenance_tasks/runs/info" folder as
    dependencies.

    Hartley McGuire

  • Rename text_area methods into textarea

    Old names are still available as aliases.

    Sean Doyle

  • Rename check_box* methods into checkbox*.

    Old names are still available as aliases.

    Jean Boussier

Action Pack

  • Fix non-GET requests not updating cookies in ActionController::TestCase.

    Jon Moss, Hartley McGuire

  • Update ActionController::Live to use a thread-pool to reuse threads across requests.

    Adam Renberg Tamm

  • Introduce safer, more explicit params handling method with params#expect such that
    params.expect(table: [ :attr ]) replaces params.require(:table).permit(:attr)

    Ensures params are filtered with consideration for the expected
    types of values, improving handling of params and avoiding ignorable
    errors caused by params tampering.

    # If the url is altered to ?person=hacked
    # Before
    params.require(:person).permit(:name, :age, pets: [:name])
    # raises NoMethodError, causing a 500 and potential error reporting
    
    # After
    params.expect(person: [ :name, :age, pets: [[:name]] ])
    # raises ActionController::ParameterMissing, correctly returning a 400 error
    

    You may also notice the new double array [[:name]]. In order to
    declare when a param is expected to be an array of parameter hashes,
    this new double array syntax is used to explicitly declare an array.
    expect requires you to declare expected arrays in this way, and will
    ignore arrays that are passed when, for example, pet: [:name] is used.

    In order to preserve compatibility, permit does not adopt the new
    double array syntax and is therefore more permissive about unexpected
    types. Using expect everywhere is recommended.

    We suggest replacing params.require(:person).permit(:name, :age)
    with the direct replacement params.expect(person: [:name, :age])
    to prevent external users from manipulating params to trigger 500
    errors. A 400 error will be returned instead, using public/400.html

    Usage of params.require(:id) should likewise be replaced with
    params.expect(:id) which is designed to ensure that params[:id]
    is a scalar and not an array or hash, also requiring the param.

    # Before
    User.find(params.require(:id)) # allows an array, altering behavior
    
    # After
    User.find(params.expect(:id)) # expect only returns non-blank permitted scalars (excludes Hash, Array, nil, "", etc)
    

    Martin Emde

  • System Testing: Disable Chrome's search engine choice by default in system tests.

    glaszig

  • Fix Request#raw_post raising NoMethodError when rack.input is nil.

    Hartley McGuire

  • Remove racc dependency by manually writing ActionDispatch::Journey::Scanner.

    Gannon McGibbon

  • Speed up ActionDispatch::Routing::Mapper::Scope#[] by merging frame hashes.

    Gannon McGibbon

  • Allow bots to ignore allow_browser.

    Matthew Nguyen

  • Deprecate drawing routes with multiple paths to make routing faster.
    You may use with_options or a loop to make drawing multiple paths easier.

    # Before
    get "/users", "/other_path", to: "users#index"
    
    # After
    get "/users", to: "users#index"
    get "/other_path", to: "users#index"
    

    Gannon McGibbon

  • Make http_cache_forever use immutable: true

    Nate Matykiewicz

  • Add config.action_dispatch.strict_freshness.

    When set to true, the ETag header takes precedence over the Last-Modified header when both are present,
    as specified by RFC 7232, Section 6.

    Defaults to false to maintain compatibility with previous versions of Rails, but is enabled as part of
    Rails 8.0 defaults.

    heka1024

  • Support immutable directive in Cache-Control

    expires_in 1.minute, public: true, immutable: true
    # Cache-Control: public, max-age=60, immutable
    

    heka1024

  • Add :wasm_unsafe_eval mapping for content_security_policy

    # Before
    policy.script_src "'wasm-unsafe-eval'"
    
    # After
    policy.script_src :wasm_unsafe_eval
    

    Joe Haig

  • Add display_capture and keyboard_map in permissions_policy

    Cyril Blaecke

  • Add connect route helper.

    Samuel Williams

Active Job

  • Deprecate sucker_punch as an adapter option.

    If you're using this adapter, change to adapter: async for the same functionality.

    Dino Maric, zzak

  • Use RAILS_MAX_THREADS in ActiveJob::AsyncAdapter. If it is not set, use 5 as default.

    heka1024

Action Mailer

Action Cable

  • Add an identifier to the event payload for the ActiveSupport::Notification transmit_subscription_confirmation.action_cable and transmit_subscription_rejection.action_cable.

    Keith Schacht

Active Storage

  • Deprecate ActiveStorage::Service::AzureStorageService.

    zzak

  • Improve ActiveStorage::Filename#sanitized method to handle special characters more effectively.
    Replace the characters "*?<> with - if they exist in the Filename to match the Filename convention of Win OS.

    Luong Viet Dung(Martin)

  • Improve InvariableError, UnpreviewableError and UnrepresentableError message.

    Include Blob ID and content_type in the messages.

    Petrik de Heus

  • Mark proxied files as immutable in their Cache-Control header

    Nate Matykiewicz

Action Mailbox

Action Text

  • Dispatch direct-upload events on attachment uploads

    When using Action Text's rich textarea, it's possible to attach files to the
    editor. Previously, that action didn't dispatch any events, which made it hard
    to react to the file uploads. For instance, if an upload failed, there was no
    way to notify the user about it, or remove the attachment from the editor.

    This commits adds new events - direct-upload:start, direct-upload:progress,
    and direct-upload:end - similar to how Active Storage's direct uploads work.

    Matheus Richard, Brad Rees

  • Add store_if_blank option to has_rich_text

    Pass store_if_blank: false to not create ActionText::RichText records when saving with a blank attribute, such as from an optional form parameter.

    class Message
      has_rich_text :content, store_if_blank: false
    end
    
    Message.create(content: "hi") # creates an ActionText::RichText
    Message.create(content: "") # does not create an ActionText::RichText
    

    Alex Ghiculescu

  • Strip content attribute if the key is present but the value is empty

    Jeremy Green

  • Rename rich_text_area methods into rich_textarea

    Old names are still available as aliases.

    Sean Doyle

  • Only sanitize content attribute when present in attachments.

    Petrik de Heus

Railties

  • Exit rails g with code 1 if generator could not be found.

    Previously rails g returned 0, which would make it harder to catch typos in scripts calling rails g.

    Christopher Özbek

  • Remove require_* statements from application.css to align with the transition from Sprockets to Propshaft.

    With Propshaft as the default asset pipeline in Rails 8, the require_tree and require_self clauses in application.css are no longer necessary, as they were specific to Sprockets. Additionally, the comment has been updated to clarify that CSS precedence now follows standard cascading order without automatic prioritization by the asset pipeline.

    Eduardo Alencar

  • Do not include redis by default in generated Dev Containers.

    Now that applications use the Solid Queue and Solid Cache gems by default, we do not need to include redis
    in the Dev Container. We will only include redis if --skip-solid is used when generating an app that uses
    Active Job or Action Cable.

    When generating a Dev Container for an existing app, we will not include redis if either of the solid gems
    are in use.

    Andrew Novoselac

  • Use Solid Cable as the default Action Cable adapter in production, configured as a separate queue database in config/database.yml. It keeps messages in a table and continuously polls for updates. This makes it possible to drop the common dependency on Redis, if it isn't needed for any other purpose. Despite polling, the performance of Solid Cable is comparable to Redis in most situations. And in all circumstances, it makes it easier to deploy Rails when Redis is no longer a required dependency for Action Cable functionality.

    DHH

  • Use Solid Queue as the default Active Job backend in production, configured as a separate queue database in config/database.yml. In a single-server deployment, it'll run as a Puma plugin. This is configured in config/deploy.yml and can easily be changed to use a dedicated jobs machine.

    DHH

  • Use Solid Cache as the default Rails.cache backend in production, configured as a separate cache database in config/database.yml.

    DHH

  • Add Rails::Rack::SilenceRequest middleware and use it via config.silence_healthcheck_path = path
    to silence requests to "/up". This prevents the Kamal-required health checks from clogging up
    the production logs.

    DHH

  • Introduce mariadb-mysql and mariadb-trilogy database options for rails new

    When used with the --devcontainer flag, these options will use mariadb as the database for the
    Dev Container. The original mysql and trilogy options will use mysql. Users who are not
    generating a Dev Container do not need to use the new options.

    Andrew Novoselac

  • Deprecate ::STATS_DIRECTORIES.

    The global constant STATS_DIRECTORIES has been deprecated in favor of
    Rails::CodeStatistics.register_directory.

    Add extra directories with Rails::CodeStatistics.register_directory(label, path):

    require "rails/code_statistics"
    Rails::CodeStatistics.register_directory('My Directory', 'path/to/dir')
    

    Petrik de Heus

  • Enable query log tags by default on development env

    This can be used to trace troublesome SQL statements back to the application
    code that generated these statements. It is also useful when using multiple
    databases because the query logs can identify which database is being used.

    Matheus Richard

  • Defer route drawing to the first request, or when url_helpers are called

    Executes the first routes reload in middleware, or when a route set's
    url_helpers receives a route call / asked if it responds to a route.
    Previously, this was executed unconditionally on boot, which can
    slow down boot time unnecessarily for larger apps with lots of routes.

    Environments like production that have config.eager_load = true will
    continue to eagerly load routes on boot.

    Gannon McGibbon

  • Generate form helpers to use textarea* methods instead of text_area* methods

    Sean Doyle

  • Add authentication generator to give a basic start to an authentication system using database-tracked sessions and password reset.

    Generate with...

    bin/rails generate authentication
    

    Generated files:

    app/models/current.rb
    app/models/user.rb
    app/models/session.rb
    app/controllers/sessions_controller.rb
    app/controllers/passwords_controller.rb
    app/mailers/passwords_mailer.rb
    app/views/sessions/new.html.erb
    app/views/passwords/new.html.erb
    app/views/passwords/edit.html.erb
    app/views/passwords_mailer/reset.html.erb
    app/views/passwords_mailer/reset.text.erb
    db/migrate/xxxxxxx_create_users.rb
    db/migrate/xxxxxxx_create_sessions.rb
    test/mailers/previews/passwords_mailer_preview.rb
    

    DHH

  • Add not-null type modifier to migration attributes.

    Generating with...

    bin/rails generate migration CreateUsers email_address:string!:uniq password_digest:string!
    

    Produces:

    class CreateUsers < ActiveRecord::Migration[8.0]
      def change
        create_table :users do |t|
          t.string :email_address, null: false
          t.string :password_digest, null: false
    
          t.timestamps
        end
        add_index :users, :email_address, unique: true
      end
    end
    

    DHH

  • Add a script folder to applications, and a scripts generator.

    The new script folder is meant to hold one-off or general purpose scripts,
    such as data migration scripts, cleanup scripts, etc.

    A new script generator allows you to create such scripts:

    bin/rails generate script my_script
    bin/rails generate script data/backfill
    

    You can run the generated script using:

    bundle exec ruby script/my_script.rb
    bundle exec ruby script/data/backfill.rb
    

    Jerome Dalbert, Haroon Ahmed

  • Deprecate bin/rake stats in favor of bin/rails stats.

    Juan Vásquez

  • Add internal page /rails/info/notes, that displays the same information as bin/rails notes.

    Deepak Mahakale

  • Add Rubocop and GitHub Actions to plugin generator.
    This can be skipped using --skip-rubocop and --skip-ci.

    Chris Oliver

  • Use Kamal for deployment by default, which includes generating a Rails-specific config/deploy.yml.
    This can be skipped using --skip-kamal. See more: https://kamal-deploy.org/

    DHH

Guides

  • The guide Classic to Zeitwerk HOWTO that documented how to migrate from
    the classic autoloader to Zeitwerk has been deleted.

    The last version of this guide can be found
    here,
    in case you need it.

    Petrik de Heus

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.1.4

Active Support

  • Improve compatibility for ActiveSupport::BroadcastLogger.

    Máximo Mussini

  • Pass options along to write_entry in handle_expired_entry method.

    Graham Cooper

  • Fix Active Support configurations deprecations.

    fatkodima

  • Fix teardown callbacks.

    Tristan Starck

  • BacktraceCleaner silence core internal methods by default.

    Jean Boussier

  • Fix delegate_missing_to allow_nil: true when called with implict self

    class Person
      delegate_missing_to :address, allow_nil: true
    
      def address
        nil
      end
    
      def berliner?
        city == "Berlin"
      end
    end
    
    Person.new.city # => nil
    Person.new.berliner? # undefined local variable or method `city' for an instance of Person (NameError)
    

    Jean Boussier

  • Work around a Ruby bug that can cause a VM crash.

    This would happen if using TaggerLogger with a Proc
    formatter on which you called object_id.

    [BUG] Object ID seen, but not in mapping table: proc
    

    Jean Boussier

  • 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

Active Model

  • No changes.

Active Record

  • Allow to eager load nested nil associations.

    fatkodima

  • Fix create_table with :auto_increment option for MySQL adapter.

    fatkodima

  • Don't load has_one associations during autosave.

    Eugene Kenny

  • Fix migration ordering for bin/rails db:prepare across databases.

    fatkodima

  • Fix alias_attribute to ignore methods defined in parent classes.

    Jean Boussier

  • Fix a performance regression in attribute methods.

    Jean Boussier

  • Fix Active Record configs variable shadowing.

    Joel Lubrano

  • Fix running migrations on other databases when database_tasks: false on primary.

    fatkodima

  • Fix non-partial inserts for models with composite identity primary keys.

    fatkodima

  • Fix ActiveRecord::Relation#touch_all with custom attribute aliased as attribute for update.

    fatkodima

  • Fix a crash when an Executor wrapped fork exit.

    Joé Dupuis

  • Fix destroy_async job for owners with composite primary keys.

    fatkodima

  • Ensure pre-7.1 migrations use legacy index names when using rename_table.

    fatkodima

  • Allow primary_key: association option to be composite.

    Nikita Vasilevsky

  • Do not try to alias on key update when raw SQL is supplied.

    Gabriel Amaral

  • Memoize key_provider from key or deterministic key_provider if any.

    Rosa Gutierrez

  • Fix upsert warning for MySQL.

    fatkodima

  • Fix predicate builder for polymorphic models referencing models with composite primary keys.

    fatkodima

  • Fix update_all/delete_all on CPK model relation with join subquery.

    Nikita Vasilevsky

  • Remove memoization to accept key_provider overridden by with_encryption_context.

    John Hawthorn

  • Raise error for Trilogy when prepared_statements is true.

    Trilogy doesn't currently support prepared statements. The error that
    applications would see is a StatementInvalid error. This doesn't quite point
    you to the fact this isn't supported. So raise a more appropriate error
    pointing to what to change.

    Eileen M. Uchitelle

  • Fix loading schema cache when all databases have disabled database tasks.

    fatkodima

  • Always request primary_key in RETURNING if no other columns requested.

    Nikita Vasilevsky

  • Handle records being loaded with Marshal without triggering schema load

    When using the old marshalling format for Active Record and loading
    a serialized instance, it didn't trigger loading the schema and defining
    attribute methods.

    Jean Boussier

  • Prevent some constant redefinition warnings when defining inherited on models.

    Adrian Hirt

  • Fix a memory perfomance regression in attribute methods.

    Attribute methods used much more memory and were slower to define than
    they should have been.

    Jean Boussier

  • 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 an issue where the IDs reader method did not return expected results
    for preloaded associations in models using composite primary keys.

    Jay Ang

  • PostgreSQL Cidr#change? detects the address prefix change.

    Taketo Takashima

  • Fix Active Record serialization to not include instantiated but not loaded associations

    Jean Boussier, Ben Kyriakou

  • Allow Sqlite3Adapter to use sqlite3 gem version 2.x

    Mike Dalessio

  • Strict loading using :n_plus_one_only does not eagerly load child associations.

    With this change, child associations are no longer eagerly loaded, to
    match intended behavior and to prevent non-deterministic order issues caused
    by calling methods like first or last. As first and last don't cause
    an N+1 by themselves, calling child associations will no longer raise.
    Fixes #49473.

    Before:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first
    # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
    person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
    

    After:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first # this is 1+1, not N+1
    # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
    person.posts.first.firm # no longer raises
    

    Reid Lynch

  • Using Model.query_constraints with a single non-primary-key column used to raise as expected, but with an
    incorrect error message. This has been fixed to raise with a more appropriate error message.

    Joshua Young

  • Fix has_one association autosave setting the foreign key attribute when it is unchanged.

    This behaviour is also inconsistent with autosaving belongs_to and can have unintended side effects like raising
    an ActiveRecord::ReadonlyAttributeError when the foreign key attribute is marked as read-only.

    Joshua Young

  • Fix an issue where ActiveRecord::Encryption configurations are not ready before the loading
    of Active Record models, when an application is eager loaded. As a result, encrypted attributes
    could be misconfigured in some cases.

    Maxime Réty

  • Properly synchronize Mysql2Adapter#active? and TrilogyAdapter#active?

    As well as disconnect! and verify!.

    This generally isn't a big problem as connections must not be shared between
    threads, but is required when running transactional tests or system tests
    and could lead to a SEGV.

    Jean Boussier

  • Fix counter caches when the foreign key is composite.

    If the model holding the counter cache had a composite primary key,
    inserting a dependent record would fail with an ArgumentError
    Expected corresponding value for...

    fatkodima

  • Fix loading of schema cache for multiple databases.

    Before this change, if you have multiple databases configured in your
    application, and had schema cache present, Rails would load the same
    cache to all databases.

    Rafael Mendonça França

  • Fix eager loading of composite primary key associations.

    relation.eager_load(:other_model) could load the wrong records if other_model
    had a composite primary key.

    Nikita Vasilevsky

  • Fix async queries returning a doubly wrapped result when hitting the query cache.

    fatkodima

  • 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 Migrations with versions older than 7.1 validating options given to
    t.references.

    Hartley McGuire

Action View

  • Action View Test Case rendered memoization.

    Sean Doyle

  • Restore the ability for templates to return any kind of object and not just strings

    Jean Boussier

  • Fix threading issue with strict locals.

    Robert Fletcher

Action Pack

  • Resolve deprecation warning in latest selenium-webdriver.

    Earlopain

  • Don't preload Selenium browser when remote.

    Noah Horton

  • Fix crash for invalid Content-Type in ShowExceptions middleware.

    Earlopain

  • Fix inconsistent results of params.deep_transform_keys.

    Iago Pimenta

  • Do not report rendered errors except 500.

    Nikita Vasilevsky

  • Improve routes source location detection.

    Jean Boussier

  • Fix Request#raw_post raising NoMethodError when rack.input is nil.

    Hartley McGuire

  • Fix url generation in nested engine when script name is empty.

    zzak

  • Fix Mime::Type.parse handling type parameters for HTTP Accept headers.

    Taylor Chaparro

  • Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
    suggested correct location for the missing template.

    Joshua Young

  • Fix a regression in 7.1.3 passing a to: option without a controller when the controller is already defined by a scope.

    Rails.application.routes.draw do
      controller :home do
        get "recent", to: "recent_posts"
      end
    end
    

    Étienne Barrié

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

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

    Jean Boussier

Active Job

  • Register autoload for ActiveJob::Arguments.

    Rafael Mendonça França

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Fixes race condition for multiple preprocessed video variants.

    Justin Searls

Action Mailbox

  • No changes.

Action Text

  • Strip content attribute if the key is present but the value is empty

    Jeremy Green

  • Only sanitize content attribute when present in attachments.

    Petrik de Heus

Railties

  • Preserve --asset-pipeline propshaft when running app:update.

    Zacharias Knudsen

  • Allow string keys for SQLCommenter.

    Ngan Pham

  • Fix derived foreign key to return correctly when association id is part of query constraints.

    Varun Sharma

  • Show warning for secret_key_base in development too.

    fatkodima

  • Fix sanitizer vendor configuration in 7.1 defaults.

    In apps where rails-html-sanitizer was not eagerly loaded, the sanitizer default could end up
    being Rails::HTML4::Sanitizer when it should be set to Rails::HTML5::Sanitizer.

    Mike Dalessio, Rafael Mendonça França

  • Revert the use of Concurrent.physical_processor_count in default Puma config

    While for many people this saves one config to set, for many others using
    a shared hosting solution, this cause the default configuration to spawn
    way more workers than reasonable.

    There is unfortunately no reliable way to detect how many cores an application
    can realistically use, and even then, assuming the application should use
    all the machine resources is often wrong.

    Jean Boussier

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Fix detection for enum columns with parallelized tests and PostgreSQL.

    Rafael Mendonça França

  • Allow to eager load nested nil associations.

    fatkodima

  • Fix swallowing ignore order warning when batching using BatchEnumerator.

    fatkodima

  • Fix memory bloat on the connection pool when using the Fiber IsolatedExecutionState.

    Jean Boussier

  • Restore inferred association class with the same modularized name.

    Justin Ko

  • Fix ActiveRecord::Base.inspect to properly explain how to load schema information.

    Jean Boussier

  • Check invalid enum options for the new syntax.

    The options using _ prefix in the old syntax are invalid in the new syntax.

    Rafael Mendonça França

  • Fix ActiveRecord::Encryption::EncryptedAttributeType#type to return
    actual cast type.

    Vasiliy Ermolovich

  • Fix create_table with :auto_increment option for MySQL adapter.

    fatkodima

Action View

  • No changes.

Action Pack

  • Fix Request#raw_post raising NoMethodError when rack.input is nil.

    Hartley McGuire

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Strip content attribute if the key is present but the value is empty

    Jeremy Green

Railties

  • Fix rails console for application with non default application constant.

    The wrongly assumed the Rails application would be named AppNamespace::Application,
    which is the default but not an obligation.

    Jean Boussier

  • Fix the default Dockerfile to include the full sqlite3 package.

    Prior to this it only included libsqlite3, so it wasn't enough to
    run rails dbconsole.

    Jerome Dalbert

  • Don't update public directory during app:update command for API-only Applications.

    y-yagi

  • Don't add bin/brakeman if brakeman is not in bundle when upgrading an application.

    Etienne Barrié

  • Remove PWA views and routes if its an API only project.

    Jean Boussier

  • Simplify generated Puma configuration

    DHH, Rafael Mendonça França

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.0

Active Support

  • Fix delegate_missing_to allow_nil: true when called with implict self

    class Person
      delegate_missing_to :address, allow_nil: true
    
      def address
        nil
      end
    
      def berliner?
        city == "Berlin"
      end
    end
    
    Person.new.city # => nil
    Person.new.berliner? # undefined local variable or method `city' for an instance of Person (NameError)
    

    Jean Boussier

  • Add logger as a dependency since it is a bundled gem candidate for Ruby 3.5

    Earlopain

  • Define Digest::UUID.nil_uuid, which returns the so-called nil UUID.

    Xavier Noria

  • Support duration type in ActiveSupport::XmlMini.

    heka1024

  • Remove deprecated ActiveSupport::Notifications::Event#children and ActiveSupport::Notifications::Event#parent_of?.

    Rafael Mendonça França

  • Remove deprecated support to call the following methods without passing a deprecator:

    • deprecate
    • deprecate_constant
    • ActiveSupport::Deprecation::DeprecatedObjectProxy.new
    • ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new
    • ActiveSupport::Deprecation::DeprecatedConstantProxy.new
    • assert_deprecated
    • assert_not_deprecated
    • collect_deprecations

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::Deprecation delegation to instance.

    Rafael Mendonça França

  • Remove deprecated SafeBuffer#clone_empty.

    Rafael Mendonça França

  • Remove deprecated #to_default_s from Array, Date, DateTime and Time.

    Rafael Mendonça França

  • Remove deprecated support to passing Dalli::Client instances to MemCacheStore.

    Rafael Mendonça França

  • Remove deprecated config.active_support.use_rfc4122_namespaced_uuids.

    Rafael Mendonça França

  • Remove deprecated config.active_support.remove_deprecated_time_with_zone_name.

    Rafael Mendonça França

  • Remove deprecated config.active_support.disable_to_s_conversion.

    Rafael Mendonça França

  • Remove deprecated support to bolding log text with positional boolean in ActiveSupport::LogSubscriber#color.

    Rafael Mendonça França

  • Remove deprecated constants ActiveSupport::LogSubscriber::CLEAR and ActiveSupport::LogSubscriber::BOLD.

    Rafael Mendonça França

  • Remove deprecated support for config.active_support.cache_format_version = 6.1.

    Rafael Mendonça França

  • Remove deprecated :pool_size and :pool_timeout options for the cache storage.

    Rafael Mendonça França

  • Warn on tests without assertions.

    ActiveSupport::TestCase now warns when tests do not run any assertions.
    This is helpful in detecting broken tests that do not perform intended assertions.

    fatkodima

  • Support hexBinary type in ActiveSupport::XmlMini.

    heka1024

  • Deprecate ActiveSupport::ProxyObject in favor of Ruby's built-in BasicObject.

    Earlopain

  • stub_const now accepts a exists: false parameter to allow stubbing missing constants.

    Jean Boussier

  • Make ActiveSupport::BacktraceCleaner copy filters and silencers on dup and clone.

    Previously the copy would still share the internal silencers and filters array,
    causing state to leak.

    Jean Boussier

  • Updating Astana with Western Kazakhstan TZInfo identifier.

    Damian Nelson

  • Add filename support for ActiveSupport::Logger.logger_outputs_to?.

    logger = Logger.new('/var/log/rails.log')
    ActiveSupport::Logger.logger_outputs_to?(logger, '/var/log/rails.log')
    

    Christian Schmidt

  • Include IPAddr#prefix when serializing an IPAddr using the
    ActiveSupport::MessagePack serializer.

    This change is backward and forward compatible — old payloads can
    still be read, and new payloads will be readable by older versions of Rails.

    Taiki Komaba

  • Add default: support for ActiveSupport::CurrentAttributes.attribute.

    class Current < ActiveSupport::CurrentAttributes
      attribute :counter, default: 0
    end
    

    Sean Doyle

  • Yield instance to Object#with block.

    client.with(timeout: 5_000) do |c|
      c.get("/commits")
    end
    

    Sean Doyle

  • Use logical core count instead of physical core count to determine the
    default number of workers when parallelizing tests.

    Jonathan Hefner

  • Fix Time.now/DateTime.now/Date.today to return results in a system timezone after #travel_to.

    There is a bug in the current implementation of #travel_to:
    it remembers a timezone of its argument, and all stubbed methods start
    returning results in that remembered timezone. However, the expected
    behavior is to return results in a system timezone.

    Aleksei Chernenkov

  • Add ErrorReported#unexpected to report precondition violations.

    For example:

    def edit
      if published?
        Rails.error.unexpected("[BUG] Attempting to edit a published article, that shouldn't be possible")
        return false
      end
      # ...
    end
    

    The above will raise an error in development and test, but only report the error in production.

    Jean Boussier

  • Make the order of read_multi and write_multi notifications for Cache::Store#fetch_multi operations match the order they are executed in.

    Adam Renberg Tamm

  • Make return values of Cache::Store#write consistent.

    The return value was not specified before. Now it returns true on a successful write,
    nil if there was an error talking to the cache backend, and false if the write failed
    for another reason (e.g. the key already exists and unless_exist: true was passed).

    Sander Verdonschot

  • Fix logged cache keys not always matching actual key used by cache action.

    Hartley McGuire

  • Improve error messages of assert_changes and assert_no_changes.

    assert_changes error messages now display objects with .inspect to make it easier
    to differentiate nil from empty strings, strings from symbols, etc.
    assert_no_changes error messages now surface the actual value.

    pcreux

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

    Earlopain

  • Fix BroadcastLogger#dup so that it duplicates the logger's broadcasts.

    Andrew Novoselac

  • Fix issue where bootstrap.rb overwrites the level of a BroadcastLogger's broadcasts.

    Andrew Novoselac

  • Fix compatibility with the semantic_logger gem.

    The semantic_logger gem doesn't behave exactly like stdlib logger in that
    SemanticLogger#level returns a Symbol while stdlib Logger#level returns an Integer.

    This caused the various LogSubscriber classes in Rails to break when assigned a
    SemanticLogger instance.

    Jean Boussier, ojab

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

    Pierre Jambet

  • Implement HashWithIndifferentAccess#to_proc.

    Previously, calling #to_proc on HashWithIndifferentAccess object used inherited #to_proc
    method from the Hash class, which was not able to access values using indifferent keys.

    fatkodima

Active Model

  • Fix a bug where type casting of string to Time and DateTime doesn't
    calculate minus minute value in TZ offset correctly.

    Akira Matsuda

  • Port the type_for_attribute method to Active Model. Classes that include
    ActiveModel::Attributes will now provide this method. This method behaves
    the same for Active Model as it does for Active Record.

    class MyModel
      include ActiveModel::Attributes
    
      attribute :my_attribute, :integer
    end
    
    MyModel.type_for_attribute(:my_attribute) # => #<ActiveModel::Type::Integer ...>
    

    Jonathan Hefner

Active Record

  • Handle commas in Sqlite3 default function definitions.

    Stephen Margheim

  • Fixes validates_associated raising an exception when configured with a
    singular association and having index_nested_attribute_errors enabled.

    Martin Spickermann

  • The constant ActiveRecord::ImmutableRelation has been deprecated because
    we want to reserve that name for a stronger sense of "immutable relation".
    Please use ActiveRecord::UnmodifiableRelation instead.

    Xavier Noria

  • Add condensed #inspect for ConnectionPool, AbstractAdapter, and
    DatabaseConfig.

    Hartley McGuire

  • Fixed a memory performance issue in Active Record attribute methods definition.

    Jean Boussier

  • Define the new Active Support notification event start_transaction.active_record.

    This event is fired when database transactions or savepoints start, and
    complements transaction.active_record, which is emitted when they finish.

    The payload has the transaction (:transaction) and the connection (:connection).

    Xavier Noria

  • Fix an issue where the IDs reader method did not return expected results
    for preloaded associations in models using composite primary keys.

    Jay Ang

  • The payload of sql.active_record Active Support notifications now has the current transaction in the :transaction key.

    Xavier Noria

  • The payload of transaction.active_record Active Support notifications now has the transaction the event is related to in the :transaction key.

    Xavier Noria

  • Define ActiveRecord::Transaction#uuid, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.

    Xavier Noria

  • Fix inference of association model on nested models with the same demodularized name.

    E.g. with the following setup:

    class Nested::Post < ApplicationRecord
      has_one :post, through: :other
    end
    

    Before, #post would infer the model as Nested::Post, but now it correctly infers Post.

    Joshua Young

  • PostgreSQL Cidr#change? detects the address prefix change.

    Taketo Takashima

  • Change BatchEnumerator#destroy_all to return the total number of affected rows.

    Previously, it always returned nil.

    fatkodima

  • Support touch_all in batches.

    Post.in_batches.touch_all
    

    fatkodima

  • Add support for :if_not_exists and :force options to create_schema.

    fatkodima

  • Fix index_errors having incorrect index in association validation errors.

    lulalala

  • Add index_errors: :nested_attributes_order mode.

    This indexes the association validation errors based on the order received by nested attributes setter, and respects the reject_if configuration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.

    lulalala

  • Add Rails.application.config.active_record.postgresql_adapter_decode_dates to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.

    Joé Dupuis

  • Association option query_constraints is deprecated in favor of foreign_key.

    Nikita Vasilevsky

  • Add ENV["SKIP_TEST_DATABASE_TRUNCATE"] flag to speed up multi-process test runs on large DBs when all tests run within default transaction.

    This cuts ~10s from the test run of HEY when run by 24 processes against the 178 tables, since ~4,000 table truncates can then be skipped.

    DHH

  • Added support for recursive common table expressions.

    Post.with_recursive(
      post_and_replies: [
        Post.where(id: 42),
        Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
      ]
    )
    

    Generates the following SQL:

    WITH RECURSIVE "post_and_replies" AS (
      (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
      UNION ALL
      (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
    )
    SELECT "posts".* FROM "posts"
    

    ClearlyClaire

  • validate_constraint can be called in a change_table block.

    ex:

    change_table :products do |t|
      t.check_constraint "price > discounted_price", name: "price_check", validate: false
      t.validate_check_constraint "price_check"
    end
    

    Cody Cutrer

  • PostgreSQLAdapter now decodes columns of type date to Date instead of string.

    Ex:

    ActiveRecord::Base.connection
         .select_value("select '2024-01-01'::date").class #=> Date
    

    Joé Dupuis

  • Strict loading using :n_plus_one_only does not eagerly load child associations.

    With this change, child associations are no longer eagerly loaded, to
    match intended behavior and to prevent non-deterministic order issues caused
    by calling methods like first or last. As first and last don't cause
    an N+1 by themselves, calling child associations will no longer raise.
    Fixes #49473.

    Before:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first
    # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
    person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
    

    After:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first # this is 1+1, not N+1
    # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
    person.posts.first.firm # no longer raises
    

    Reid Lynch

  • Allow Sqlite3Adapter to use sqlite3 gem version 2.x.

    Mike Dalessio

  • Allow ActiveRecord::Base#pluck to accept hash values.

    # Before
    Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
    
    # After
    Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
    

    fatkodima

  • Raise an ActiveRecord::ActiveRecordError error when the MySQL database returns an invalid version string.

    Kevin McPhillips

  • ActiveRecord::Base.transaction now yields an ActiveRecord::Transaction object.

    This allows to register callbacks on it.

    Article.transaction do |transaction|
      article.update(published: true)
      transaction.after_commit do
        PublishNotificationMailer.with(article: article).deliver_later
      end
    end
    

    Jean Boussier

  • Add ActiveRecord::Base.current_transaction.

    Returns the current transaction, to allow registering callbacks on it.

    Article.current_transaction.after_commit do
      PublishNotificationMailer.with(article: article).deliver_later
    end
    

    Jean Boussier

  • Add ActiveRecord.after_all_transactions_commit callback.

    Useful for code that may run either inside or outside a transaction and needs
    to perform work after the state changes have been properly persisted.

    def publish_article(article)
      article.update(published: true)
      ActiveRecord.after_all_transactions_commit do
        PublishNotificationMailer.with(article: article).deliver_later
      end
    end
    

    In the above example, the block is either executed immediately if called outside
    of a transaction, or called after the open transaction is committed.

    If the transaction is rolled back, the block isn't called.

    Jean Boussier

  • Add the ability to ignore counter cache columns until they are backfilled.

    Starting to use counter caches on existing large tables can be troublesome, because the column
    values must be backfilled separately of the column addition (to not lock the table for too long)
    and before the use of :counter_cache (otherwise methods like size/any?/etc, which use
    counter caches internally, can produce incorrect results). People usually use database triggers
    or callbacks on child associations while backfilling before introducing a counter cache
    configuration to the association.

    Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:

    class Comment < ApplicationRecord
      belongs_to :post, counter_cache: { active: false }
    end
    

    While the counter cache is not "active", the methods like size/any?/etc will not use it,
    but get the results directly from the database. After the counter cache column is backfilled, simply
    remove the { active: false } part from the counter cache definition, and it will now be used by the
    mentioned methods.

    fatkodima

  • Retry known idempotent SELECT queries on connection-related exceptions.

    SELECT queries we construct by walking the Arel tree and / or with known model attributes
    are idempotent and can safely be retried in the case of a connection error. Previously,
    adapters such as TrilogyAdapter would raise ActiveRecord::ConnectionFailed: Trilogy::EOFError
    when encountering a connection error mid-request.

    Adrianna Chang

  • Allow association's foreign_key to be composite.

    query_constraints option was the only way to configure a composite foreign key by passing an Array.
    Now it's possible to pass an Array value as foreign_key to achieve the same behavior of an association.

    Nikita Vasilevsky

  • Allow association's primary_key to be composite.

    Association's primary_key can be composite when derived from associated model primary_key or query_constraints.
    Now it's possible to explicitly set it as composite on the association.

    Nikita Vasilevsky

  • Add config.active_record.permanent_connection_checkout setting.

    Controls whether ActiveRecord::Base.connection raises an error, emits a deprecation warning, or neither.

    ActiveRecord::Base.connection checkouts a database connection from the pool and keeps it leased until the end of
    the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
    is available connections.

    This configuration can be used to track down and eliminate code that calls ActiveRecord::Base.connection and
    migrate it to use ActiveRecord::Base.with_connection instead.

    The default behavior remains unchanged, and there is currently no plans to change the default.

    Jean Boussier

  • Add dirties option to uncached.

    This adds a dirties option to ActiveRecord::Base.uncached and
    ActiveRecord::ConnectionAdapters::ConnectionPool#uncached.

    When set to true (the default), writes will clear all query caches belonging to the current thread.
    When set to false, writes to the affected connection pool will not clear any query cache.

    This is needed by Solid Cache so that cache writes do not clear query caches.

    Donal McBreen

  • Deprecate ActiveRecord::Base.connection in favor of .lease_connection.

    The method has been renamed as lease_connection to better reflect that the returned
    connection will be held for the duration of the request or job.

    This deprecation is a soft deprecation, no warnings will be issued and there is no
    current plan to remove the method.

    Jean Boussier

  • Deprecate ActiveRecord::ConnectionAdapters::ConnectionPool#connection.

    The method has been renamed as lease_connection to better reflect that the returned
    connection will be held for the duration of the request or job.

    Jean Boussier

  • Expose a generic fixture accessor for fixture names that may conflict with Minitest.

    assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
    assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
    

    Jean Boussier

  • Using Model.query_constraints with a single non-primary-key column used to raise as expected, but with an
    incorrect error message.

    This has been fixed to raise with a more appropriate error message.

    Joshua Young

  • Fix has_one association autosave setting the foreign key attribute when it is unchanged.

    This behavior is also inconsistent with autosaving belongs_to and can have unintended side effects like raising
    an ActiveRecord::ReadonlyAttributeError when the foreign key attribute is marked as read-only.

    Joshua Young

  • Remove deprecated behavior that would rollback a transaction block when exited using return, break or throw.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_record.commit_transaction_on_non_local_return.

    Rafael Mendonça França

  • Remove deprecated support to pass rewhere to ActiveRecord::Relation#merge.

    Rafael Mendonça França

  • Remove deprecated support to pass deferrable: true to add_foreign_key.

    Rafael Mendonça França

  • Remove deprecated support to quote ActiveSupport::Duration.

    Rafael Mendonça França

  • Remove deprecated #quote_bound_value.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass.

    Rafael Mendonça França

  • Remove deprecated support to apply #connection_pool_list, #active_connections?, #clear_active_connections!,
    #clear_reloadable_connections!, #clear_all_connections! and #flush_idle_connections! to the connections pools
    for the current role when the role argument isn't provided.

    Rafael Mendonça França

  • Remove deprecated #all_connection_pools.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::SchemaCache#data_sources.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::SchemaCache.load_from.

    Rafael Mendonça França

  • Remove deprecated #all_foreign_keys_valid? from database adapters.

    Rafael Mendonça França

  • Remove deprecated support to passing coder and class as second argument to serialize.

    Rafael Mendonça França

  • Remove deprecated support to ActiveRecord::Base#read_attribute(:id) to return the custom primary key value.

    Rafael Mendonça França

  • Remove deprecated TestFixtures.fixture_path.

    Rafael Mendonça França

  • Remove deprecated behavior to support referring to a singular association by its plural name.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_record.allow_deprecated_singular_associations_name.

    Rafael Mendonça França

  • Remove deprecated support to passing SchemaMigration and InternalMetadata classes as arguments to
    ActiveRecord::MigrationContext.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Migration.check_pending! method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.runtime method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.runtime= method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.reset_runtime method.

    Rafael Mendonça França

  • Remove deprecated support to define explain in the connection adapter with 2 arguments.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ActiveJobRequiredError.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_active_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_reloadable_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_all_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.flush_idle_connections!.

    Rafael Mendonça França

  • Remove deprecated name argument from ActiveRecord::Base.remove_connection.

    Rafael Mendonça França

  • Remove deprecated support to call alias_attribute with non-existent attribute names.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.active_record.suppress_multiple_database_warning.

    Rafael Mendonça França

  • Add ActiveRecord::Encryption::MessagePackMessageSerializer.

    Serialize data to the MessagePack format, for efficient storage in binary columns.

    The binary encoding requires around 30% less space than the base64 encoding
    used by the default serializer.

    Donal McBreen

  • Add support for encrypting binary columns.

    Ensure encryption and decryption pass Type::Binary::Data around for binary data.

    Previously encrypting binary columns with the ActiveRecord::Encryption::MessageSerializer
    incidentally worked for MySQL and SQLite, but not PostgreSQL.

    Donal McBreen

  • Deprecated ENV["SCHEMA_CACHE"] in favor of schema_cache_path in the database configuration.

    Rafael Mendonça França

  • Add ActiveRecord::Base.with_connection as a shortcut for leasing a connection for a short duration.

    The leased connection is yielded, and for the duration of the block, any call to ActiveRecord::Base.connection
    will yield that same connection.

    This is useful to perform a few database operations without causing a connection to be leased for the
    entire duration of the request or job.

    Jean Boussier

  • Deprecate config.active_record.warn_on_records_fetched_greater_than now that sql.active_record
    notification includes :row_count field.

    Jason Nochlin

  • The fix ensures that the association is joined using the appropriate join type
    (either inner join or left outer join) based on the existing joins in the scope.

    This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.

    Example:

    # `associated` will use `LEFT JOIN` instead of using `JOIN`
    Post.left_joins(:author).where.associated(:author)
    

    Saleh Alhaddad

  • Fix an issue where ActiveRecord::Encryption configurations are not ready before the loading
    of Active Record models, when an application is eager loaded. As a result, encrypted attributes
    could be misconfigured in some cases.

    Maxime Réty

  • Deprecate defining an enum with keyword arguments.

    class Function > ApplicationRecord
      # BAD
      enum color: [:red, :blue],
           type: [:instance, :class]
    
      # GOOD
      enum :color, [:red, :blue]
      enum :type, [:instance, :class]
    end
    

    Hartley McGuire

  • Add config.active_record.validate_migration_timestamps option for validating migration timestamps.

    When set, validates that the timestamp prefix for a migration is no more than a day ahead of
    the timestamp associated with the current time. This is designed to prevent migrations prefixes
    from being hand-edited to future timestamps, which impacts migration generation and other
    migration commands.

    Adrianna Chang

  • Properly synchronize Mysql2Adapter#active? and TrilogyAdapter#active?.

    As well as disconnect! and verify!.

    This generally isn't a big problem as connections must not be shared between
    threads, but is required when running transactional tests or system tests
    and could lead to a SEGV.

    Jean Boussier

  • Support :source_location tag option for query log tags.

    config.active_record.query_log_tags << :source_location
    

    Calculating the caller location is a costly operation and should be used primarily in development
    (note, there is also a config.active_record.verbose_query_logs that serves the same purpose)
    or occasionally on production for debugging purposes.

    fatkodima

  • Add an option to ActiveRecord::Encryption::Encryptor to disable compression.

    Allow compression to be disabled by setting compress: false

      class User
        encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
      end
    

    Donal McBreen

  • Deprecate passing strings to ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename.

    A ActiveRecord::DatabaseConfigurations::DatabaseConfig object should be passed instead.

    Rafael Mendonça França

  • Add row_count field to sql.active_record notification.

    This field returns the amount of rows returned by the query that emitted the notification.

    This metric is useful in cases where one wants to detect queries with big result sets.

    Marvin Bitterlich

  • Consistently raise an ArgumentError when passing an invalid argument to a nested attributes association writer.

    Previously, this would only raise on collection associations and produce a generic error on singular associations.

    Now, it will raise on both collection and singular associations.

    Joshua Young

  • 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 Migrations with versions older than 7.1 validating options given to
    add_reference and t.references.

    Hartley McGuire

  • Add <role>_types class method to ActiveRecord::DelegatedType so that the delegated types can be introspected.

    JP Rosevear

  • Make schema_dump, query_cache, replica and database_tasks configurable via DATABASE_URL.

    This wouldn't always work previously because boolean values would be interpreted as strings.

    e.g. DATABASE_URL=postgres://localhost/foo?schema_dump=false now properly disable dumping the schema
    cache.

    Mike Coutermarsh, Jean Boussier

  • Introduce ActiveRecord::Transactions::ClassMethods#set_callback.

    It is identical to ActiveSupport::Callbacks::ClassMethods#set_callback
    but with support for after_commit and after_rollback callback options.

    Joshua Young

  • Make ActiveRecord::Encryption::Encryptor agnostic of the serialization format used for encrypted data.

    Previously, the encryptor instance only allowed an encrypted value serialized as a String to be passed to the message serializer.

    Now, the encryptor lets the configured message_serializer decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize ActiveRecord::Encryption::Message objects using a type other than String.

    The default ActiveRecord::Encryption::MessageSerializer already ensures that only String objects are passed for deserialization.

    Maxime Réty

  • Fix encrypted_attribute? to take into account context properties passed to encrypts.

    Maxime Réty

  • The object returned by explain now responds to pluck, first,
    last, average, count, maximum, minimum, and sum. Those
    new methods run EXPLAIN on the corresponding queries:

    User.all.explain.count
    # EXPLAIN SELECT COUNT(*) FROM `users`
    # ...
    
    User.all.explain.maximum(:id)
    # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
    # ...
    

    Petrik de Heus

  • Fixes an issue where validates_associated :on option wasn't respected
    when validating associated records.

    Austen Madden, Alex Ghiculescu, Rafał Brize

  • Allow overriding SQLite defaults from database.yml.

    Any PRAGMA configuration set under the pragmas key in the configuration
    file takes precedence over Rails' defaults, and additional PRAGMAs can be
    set as well.

    database: storage/development.sqlite3
    timeout: 5000
    pragmas:
      journal_mode: off
      temp_store: memory
    

    Stephen Margheim

  • Remove warning message when running SQLite in production, but leave it unconfigured.

    There are valid use cases for running SQLite in production. However, it must be done
    with care, so instead of a warning most users won't see anyway, it's preferable to
    leave the configuration commented out to force them to think about having the database
    on a persistent volume etc.

    Jacopo Beschi, Jean Boussier

  • Add support for generated columns to the SQLite3 adapter.

    Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
    This adds support for those to the SQLite3 adapter.

    create_table :users do |t|
      t.string :name
      t.virtual :name_upper, type: :string, as: 'UPPER(name)'
      t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
    end
    

    Stephen Margheim

  • TrilogyAdapter: ignore host if socket parameter is set.

    This allows to configure a connection on a UNIX socket via DATABASE_URL:

    DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
    

    Jean Boussier

  • Make assert_queries_count, assert_no_queries, assert_queries_match, and
    assert_no_queries_match assertions public.

    To assert the expected number of queries are made, Rails internally uses assert_queries_count and
    assert_no_queries. To assert that specific SQL queries are made, assert_queries_match and
    assert_no_queries_match are used. These assertions can now be used in applications as well.

    class ArticleTest < ActiveSupport::TestCase
      test "queries are made" do
        assert_queries_count(1) { Article.first }
      end
    
      test "creates a foreign key" do
        assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
          @connection.add_foreign_key(:comments, :posts)
        end
      end
    end
    

    Petrik de Heus, fatkodima

  • Fix has_secure_token calls the setter method on initialize.

    Abeid Ahmed

  • When using a DATABASE_URL, allow for a configuration to map the protocol in the URL to a specific database
    adapter. This allows decoupling the adapter the application chooses to use from the database connection details
    set in the deployment environment.

    # ENV['DATABASE_URL'] = "mysql://localhost/example_database"
    config.active_record.protocol_adapters.mysql = "trilogy"
    # will connect to MySQL using the trilogy adapter
    

    Jean Boussier, Kevin McPhillips

  • In cases where MySQL returns warning_count greater than zero, but returns no warnings when
    the SHOW WARNINGS query is executed, ActiveRecord.db_warnings_action proc will still be
    called with a generic warning message rather than silently ignoring the warning(s).

    Kevin McPhillips

  • DatabaseConfigurations#configs_for accepts a symbol in the name parameter.

    Andrew Novoselac

  • 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

  • Make the output of ActiveRecord::Core#inspect configurable.

    By default, calling inspect on a record will yield a formatted string including just the id.

    Post.first.inspect #=> "#<Post id: 1>"
    

    The attributes to be included in the output of inspect can be configured with
    ActiveRecord::Core#attributes_for_inspect.

    Post.attributes_for_inspect = [:id, :title]
    Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
    

    With attributes_for_inspect set to :all, inspect will list all the record's attributes.

    Post.attributes_for_inspect = :all
    Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
    

    In development and test mode, attributes_for_inspect will be set to :all by default.

    You can also call full_inspect to get an inspection with all the attributes.

    The attributes in attribute_for_inspect will also be used for pretty_print.

    Andrew Novoselac

  • Don't mark attributes as changed when reassigned to Float::INFINITY or
    -Float::INFINITY.

    Maicol Bentancor

  • Support the RETURNING clause for MariaDB.

    fatkodima, Nikolay Kondratyev

  • The SQLite3 adapter now implements the supports_deferrable_constraints? contract.

    Allows foreign keys to be deferred by adding the :deferrable key to the foreign_key options.

    add_reference :person, :alias, foreign_key: { deferrable: :deferred }
    add_reference :alias, :person, foreign_key: { deferrable: :deferred }
    

    Stephen Margheim

  • Add the set_constraints helper to PostgreSQL connections.

    Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
    
    Post.transaction do
      Post.connection.set_constraints(:deferred)
      p = Post.create!(user_id: -1)
      u = User.create!
      p.user = u
      p.save!
    end
    

    Cody Cutrer

  • Include ActiveModel::API in ActiveRecord::Base.

    Sean Doyle

  • Ensure #signed_id outputs url_safe strings.

    Jason Meller

  • Add nulls_last and working desc.nulls_first for MySQL.

    Tristan Fellows

  • Allow for more complex hash arguments for order which mimics where in ActiveRecord::Relation.

    Topic.includes(:posts).order(posts: { created_at: :desc })
    

    Myles Boone

Action View

  • Fix templates with strict locals to also include local_assigns.

    Previously templates defining strict locals wouldn't receive the local_assigns
    hash.

    Jean Boussier

  • Add queries count to template rendering instrumentation.

    # Before
    Completed 200 OK in 3804ms (Views: 41.0ms | ActiveRecord: 33.5ms | Allocations: 112788)
    
    # After
    Completed 200 OK in 3804ms (Views: 41.0ms | ActiveRecord: 33.5ms (2 queries, 1 cached) | Allocations: 112788)
    

    fatkodima

  • Raise ArgumentError if :renderable object does not respond to #render_in.

    Sean Doyle

  • Add the nonce: true option for stylesheet_link_tag helper to support automatic nonce generation for Content Security Policy.

    Works the same way as javascript_include_tag nonce: true does.

    Akhil G Krishnan, AJ Esler

  • Parse ActionView::TestCase#rendered HTML content as Nokogiri::XML::DocumentFragment instead of Nokogiri::XML::Document.

    Sean Doyle

  • Rename ActionView::TestCase::Behavior::Content to ActionView::TestCase::Behavior::RenderedViewContent.

    Make RenderedViewContent inherit from String. Make private API with :nodoc:

    Sean Doyle

  • Deprecate passing nil as value for the model: argument to the form_with method.

    Collin Jilbert

  • Alias field_set_tag helper to fieldset_tag to match <fieldset> element.

    Sean Doyle

  • Deprecate passing content to void elements when using tag.br type tag builders.

    Hartley McGuire

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

    Earlopain

  • Automatically discard the implicit locals injected by collection rendering for template that can't accept them.

    When rendering a collection, two implicit variables are injected, which breaks templates with strict locals.

    Now they are only passed if the template will actually accept them.

    Yasha Krasnou, Jean Boussier

  • Fix @rails/ujs calling start() an extra time when using bundlers.

    Hartley McGuire, Ryunosuke Sato

  • Fix the capture view helper compatibility with HAML and Slim.

    When a blank string was captured in HAML or Slim (and possibly other template engines)
    it would instead return the entire buffer.

    Jean Boussier

  • Updated @rails/ujs files to ignore certain data-* attributes when element is contenteditable.

    This fix was already landed in >= 7.0.4.3, < 7.1.0.
    [CVE-2023-23913]

    Ryunosuke Sato

  • Added validation for HTML tag names in the tag and content_tag helper method.

    The tag and content_tag method now checks that the provided tag name adheres to the HTML
    specification. If an invalid HTML tag name is provided, the method raises an ArgumentError
    with an appropriate error message.

    Examples:

    # Raises ArgumentError: Invalid HTML5 tag name: 12p
    content_tag("12p") # Starting with a number
    
    # Raises ArgumentError: Invalid HTML5 tag name: ""
    content_tag("") # Empty tag name
    
    # Raises ArgumentError: Invalid HTML5 tag name: div/
    tag("div/") # Contains a solidus
    
    # Raises ArgumentError: Invalid HTML5 tag name: "image file"
    tag("image file") # Contains a space
    

    Akhil G Krishnan

Action Pack

  • Allow bots to ignore allow_browser.

    Matthew Nguyen

  • Include the HTTP Permissions-Policy on non-HTML Content-Types
    [CVE-2024-28103]

    Aaron Patterson, Zack Deveau

  • Fix Mime::Type.parse handling type parameters for HTTP Accept headers.

    Taylor Chaparro

  • Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
    suggested correct location for the missing template.

    Joshua Young

  • Add save_and_open_page helper to IntegrationTest.

    save_and_open_page is a helpful helper to keep a short feedback loop when working on system tests.
    A similar helper with matching signature has been added to integration tests.

    Joé Dupuis

  • Fix a regression in 7.1.3 passing a to: option without a controller when the controller is already defined by a scope.

    Rails.application.routes.draw do
      controller :home do
        get "recent", to: "recent_posts"
      end
    end
    

    Étienne Barrié

  • Request Forgery takes relative paths into account.

    Stefan Wienert

  • Add ".test" as a default allowed host in development to ensure smooth golden-path setup with puma.dev.

    DHH

  • Add allow_browser to set minimum browser versions for the application.

    A browser that's blocked will by default be served the file in public/406-unsupported-browser.html with a HTTP status code of "406 Not Acceptable".

    class ApplicationController < ActionController::Base
      # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting + :has
      allow_browser versions: :modern
    end
    
    class ApplicationController < ActionController::Base
      # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
      allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
    end
    
    class MessagesController < ApplicationController
      # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
      allow_browser versions: { opera: 104, chrome: 119 }, only: :show
    end
    

    DHH

  • Add rate limiting API.

    class SessionsController < ApplicationController
      rate_limit to: 10, within: 3.minutes, only: :create
    end
    
    class SignupsController < ApplicationController
      rate_limit to: 1000, within: 10.seconds,
        by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups!" }, only: :new
    end
    

    DHH, Jean Boussier

  • Add image/svg+xml to the compressible content types of ActionDispatch::Static.

    Georg Ledermann

  • Add instrumentation for ActionController::Live#send_stream.

    Allows subscribing to send_stream events. The event payload contains the filename, disposition, and type.

    Hannah Ramadan

  • Add support for with_routing test helper in ActionDispatch::IntegrationTest.

    Gannon McGibbon

  • Remove deprecated support to set Rails.application.config.action_dispatch.show_exceptions to true and false.

    Rafael Mendonça França

  • Remove deprecated speaker, vibrate, and vr permissions policy directives.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type.

    Rafael Mendonça França

  • Deprecate Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality.

    Rafael Mendonça França

  • Remove deprecated comparison between ActionController::Parameters and Hash.

    Rafael Mendonça França

  • Remove deprecated constant AbstractController::Helpers::MissingHelperError.

    Rafael Mendonça França

  • Fix a race condition that could cause a Text file busy - chromedriver
    error with parallel system tests.

    Matt Brictson

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

    Hartley McGuire

  • Remove deprecated constant ActionDispatch::IllegalStateError.

    Rafael Mendonça França

  • Add parameter filter capability for redirect locations.

    It uses the config.filter_parameters to match what needs to be filtered.
    The result would be like this:

    Redirected to http://secret.foo.bar?username=roque&password=[FILTERED]
    

    Fixes #14055.

    Roque Pinel, Trevor Turk, tonytonyjan

Active Job

  • All tests now respect the active_job.queue_adapter config.

    Previously if you had set config.active_job.queue_adapter in your config/application.rb
    or config/environments/test.rb file, the adapter you selected was previously not used consistently
    across all tests. In some tests your adapter would be used, but other tests would use the TestAdapter.

    In Rails 7.2, all tests will respect the queue_adapter config if provided. If no config is provided,
    the TestAdapter will continue to be used.

    See #48585 for more details.

    Alex Ghiculescu

  • Make Active Job transaction aware when used conjointly with Active Record.

    A common mistake with Active Job is to enqueue jobs from inside a transaction,
    causing them to potentially be picked and ran by another process, before the
    transaction is committed, which may result in various errors.

    Topic.transaction do
      topic = Topic.create(...)
      NewTopicNotificationJob.perform_later(topic)
    end
    

    Now Active Job will automatically defer the enqueuing to after the transaction is committed,
    and drop the job if the transaction is rolled back.

    Various queue implementations can choose to disable this behavior, and users can disable it,
    or force it on a per job basis:

    class NewTopicNotificationJob < ApplicationJob
      self.enqueue_after_transaction_commit = :never # or `:always` or `:default`
    end
    

    Jean Boussier, Cristian Bica

  • Do not trigger immediate loading of ActiveJob::Base when loading ActiveJob::TestHelper.

    Maxime Réty

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

    Joshua Young

  • Remove deprecated :exponentially_longer value for the :wait in retry_on.

    Rafael Mendonça França

  • Remove deprecated support to set numeric values to scheduled_at attribute.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_job.use_big_decimal_serialize.

    Rafael Mendonça França

  • Remove deprecated primitive serializer for BigDecimal arguments.

    Rafael Mendonça França

Action Mailer

  • Remove deprecated params via :args for assert_enqueued_email_with.

    Rafael Mendonça França

  • Remove deprecated config.action_mailer.preview_path.

    Rafael Mendonça França

Action Cable

  • Bring ActionCable::Connection::TestCookieJar in alignment with ActionDispatch::Cookies::CookieJar in regards to setting the cookie value.

    Before:

    cookies[:foo] = { value: "bar" }
    puts cookies[:foo] # => { value: "bar" }
    

    After:

    cookies[:foo] = { value: "bar" }
    puts cookies[:foo] # => "bar"
    

    Justin Ko

  • Record ping on every Action Cable message.

    Previously only ping and welcome message types were keeping the connection active.
    Now every Action Cable message updates the pingedAt value, preventing the connection
    from being marked as stale.

    yauhenininjia

  • Add two new assertion methods for Action Cable test cases: assert_has_no_stream
    and assert_has_no_stream_for.

    These methods can be used to assert that a stream has been stopped, e.g. via
    stop_stream or stop_stream_for. They complement the already existing
    assert_has_stream and assert_has_stream_for methods.

    assert_has_no_stream "messages"
    assert_has_no_stream_for User.find(42)
    

    Sebastian Pöll, Junichi Sato

Active Storage

  • Remove deprecated config.active_storage.silence_invalid_content_types_warning.

    Rafael Mendonça França

  • Remove deprecated config.active_storage.replace_on_assign_to_many.

    Rafael Mendonça França

  • Add support for custom key in ActiveStorage::Blob#compose.

    Elvin Efendiev

  • Add image/webp to config.active_storage.web_image_content_types when load_defaults "7.2"
    is set.

    Lewis Buckley

  • Fix JSON-encoding of ActiveStorage::Filename instances.

    Jonathan del Strother

  • Fix N+1 query when fetching preview images for non-image assets.

    Aaron Patterson & Justin Searls

  • Fix all Active Storage database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

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

    Chedli Bourguiba

  • Fix ActiveStorage::Representations::ProxyController to proxy untracked
    variants.

    Chedli Bourguiba

  • When using the preprocessed: true option, avoid enqueuing transform jobs
    for blobs that are not representable.

    Chedli Bourguiba

  • Prevent ActiveStorage::Blob#preview to generate a variant if an empty variation is passed.

    Calls to #url, #key or #download will now use the original preview
    image instead of generating a variant with the exact same dimensions.

    Chedli Bourguiba

  • Process preview image variant when calling ActiveStorage::Preview#processed.

    For example, attached_pdf.preview(:thumb).processed will now immediately
    generate the full-sized preview image and the :thumb variant of it.
    Previously, the :thumb variant would not be generated until a further call
    to e.g. processed.url.

    Chedli Bourguiba and Jonathan Hefner

  • 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 preprocessed: true option for named variants of previewable files.

    Nico Wenterodt

  • Allow accepting service as a proc as well in has_one_attached and has_many_attached.

    Yogesh Khater

Action Mailbox

  • Fix all Action Mailbox database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

Action Text

  • Only sanitize content attribute when present in attachments.

    Petrik de Heus

  • Sanitize ActionText HTML ContentAttachment in Trix edit view
    [CVE-2024-32464]

    Aaron Patterson, Zack Deveau

  • Use includes instead of eager_load for with_all_rich_text.

    Petrik de Heus

  • Delegate ActionText::Content#deconstruct to Nokogiri::XML::DocumentFragment#elements.

    content = ActionText::Content.new <<~HTML
      <h1>Hello, world</h1>
    
      <div>The body</div>
    HTML
    
    content => [h1, div]
    
    assert_pattern { h1 => { content: "Hello, world" } }
    assert_pattern { div => { content: "The body" } }
    

    Sean Doyle

  • Fix all Action Text database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

  • Compile ESM package that can be used directly in the browser as actiontext.esm.js

    Matias Grunberg

  • Fix using actiontext.js with Sprockets.

    Matias Grunberg

  • Upgrade Trix to 2.0.7

    Hartley McGuire

  • Fix using Trix with Sprockets.

    Hartley McGuire

Railties

  • The new bin/rails boot command boots the application and exits. Supports the
    standard -e/--environment options.

    Xavier Noria

  • Create a Dev Container Generator that generates a Dev Container setup based on the current configuration
    of the application. Usage:

    bin/rails devcontainer

    Andrew Novoselac

  • Add Rubocop and GitHub Actions to plugin generator.
    This can be skipped using --skip-rubocop and --skip-ci.

    Chris Oliver

  • Remove support for oracle, sqlserver and JRuby specific database adapters from the
    rails new and rails db:system:change commands.

    The supported options are sqlite3, mysql, postgresql and trilogy.

    Andrew Novoselac

  • Add options to bin/rails app:update.

    bin/rails app:update now supports the same generic options that generators do:

    • --force: Accept all changes to existing files
    • --skip: Refuse all changes to existing files
    • --pretend: Don't make any changes
    • --quiet: Don't output all changes made

    Étienne Barrié

  • Implement Rails console commands and helpers with IRB v1.13's extension APIs.

    Rails console users will now see helper, controller, new_session, and app under
    IRB help message's Helper methods category. And reload! command will be displayed under
    the new Rails console commands category.

    Prior to this change, Rails console's commands and helper methods are added through IRB's
    private components and don't show up in its help message, which led to poor discoverability.

    Stan Lo

  • Remove deprecated Rails::Generators::Testing::Behaviour.

    Rafael Mendonça França

  • Remove deprecated find_cmd_and_exec console helper.

    Rafael Mendonça França

  • Remove deprecated Rails.config.enable_dependency_loading.

    Rafael Mendonça França

  • Remove deprecated Rails.application.secrets.

    Rafael Mendonça França

  • Generated Gemfile will include require: "debug/prelude" for the debug gem.

    Requiring debug gem directly automatically activates it, which could introduce
    additional overhead and memory usage even without entering a debugging session.

    By making Bundler require debug/prelude instead, developers can keep their access
    to breakpoint methods like debugger or binding.break, but the debugger won't be
    activated until a breakpoint is hit.

    Stan Lo

  • Skip generating a test job in ci.yml when a new application is generated with the
    --skip-test option.

    Steve Polito

  • Update the .node-version file conditionally generated for new applications to 20.11.1

    Steve Polito

  • Fix sanitizer vendor configuration in 7.1 defaults.

    In apps where rails-html-sanitizer was not eagerly loaded, the sanitizer default could end up
    being Rails::HTML4::Sanitizer when it should be set to Rails::HTML5::Sanitizer.

    Mike Dalessio, Rafael Mendonça França

  • Set action_mailer.default_url_options values in development and test.

    Prior to this commit, new Rails applications would raise ActionView::Template::Error
    if a mailer included a url built with a *_path helper.

    Steve Polito

  • Introduce Rails::Generators::Testing::Assertions#assert_initializer.

    Compliments the existing initializer generator action.

    assert_initializer "mail_interceptors.rb"
    

    Steve Polito

  • Generate a .devcontainer folder and its contents when creating a new app.

    The .devcontainer folder includes everything needed to boot the app and do development in a remote container.

    The container setup includes:

    • A redis container for Kredis, ActionCable etc.
    • A database (SQLite, Postgres, MySQL or MariaDB)
    • A Headless chrome container for system tests
    • Active Storage configured to use the local disk and with preview features working

    If any of these options are skipped in the app setup they will not be included in the container configuration.

    These files can be skipped using the --skip-devcontainer option.

    Andrew Novoselac & Rafael Mendonça França

  • Introduce SystemTestCase#served_by for configuring the System Test application server.

    By default this is localhost. This method allows the host and port to be specified manually.

    class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
      served_by host: "testserver", port: 45678
    end
    

    Andrew Novoselac & Rafael Mendonça França

  • bin/rails test will no longer load files named *_test.rb if they are located in the fixtures folder.

    Edouard Chin

  • Ensure logger tags configured with config.log_tags are still active in request.action_dispatch handlers.

    KJ Tsanaktsidis

  • Setup jemalloc in the default Dockerfile for memory optimization.

    Matt Almeida, Jean Boussier

  • Commented out lines in .railsrc file should not be treated as arguments when using
    rails new generator command. Update ARGVScrubber to ignore text after # symbols.

    Willian Tenfen

  • Skip CSS when generating APIs.

    Ruy Rocha

  • Rails console now indicates application name and the current Rails environment:

    my-app(dev)> # for RAILS_ENV=development
    my-app(test)> # for RAILS_ENV=test
    my-app(prod)> # for RAILS_ENV=production
    my-app(my_env)> # for RAILS_ENV=my_env
    

    The application name is derived from the application's module name from config/application.rb.
    For example, MyApp will displayed as my-app in the prompt.

    Additionally, the environment name will be colorized when the environment is
    development (blue), test (blue), or production (red), if your
    terminal supports it.

    Stan Lo

  • Ensure autoload_paths, autoload_once_paths, eager_load_paths, and
    load_paths only have directories when initialized from engine defaults.

    Previously, files under the app directory could end up there too.

    Takumasa Ochi

  • Prevent unnecessary application reloads in development.

    Previously, some files outside autoload paths triggered unnecessary reloads.
    With this fix, application reloads according to Rails.autoloaders.main.dirs,
    thereby preventing unnecessary reloads.

    Takumasa Ochi

  • Use oven-sh/setup-bun in GitHub CI when generating an app with Bun.

    TangRufus

  • Disable pidfile generation in the production environment.

    Hans Schnedlitz

  • Set config.action_view.annotate_rendered_view_with_filenames to true in
    the development environment.

    Adrian Marin

  • Support the BACKTRACE environment variable to turn off backtrace cleaning.

    Useful for debugging framework code:

    BACKTRACE=1 bin/rails server
    

    Alex Ghiculescu

  • Raise ArgumentError when reading config.x.something with arguments:

    config.x.this_works.this_raises true # raises ArgumentError
    

    Sean Doyle

  • Add default PWA files for manifest and service-worker that are served from app/views/pwa and can be dynamically rendered through ERB. Mount these files explicitly at the root with default routes in the generated routes file.

    DHH

  • Updated system tests to now use headless Chrome by default for the new applications.

    DHH

  • Add GitHub CI files for Dependabot, Brakeman, RuboCop, and running tests by default. Can be skipped with --skip-ci.

    DHH

  • Add Brakeman by default for static analysis of security vulnerabilities. Allow skipping with --skip-brakeman option.

    vipulnsward

  • Add RuboCop with rules from rubocop-rails-omakase by default. Skip with --skip-rubocop.

    DHH and zzak

  • Use bin/rails runner --skip-executor to not wrap the runner script with an
    Executor.

    Ben Sheldon

  • Fix isolated engines to take ActiveRecord::Base.table_name_prefix into consideration.

    This will allow for engine defined models, such as inside Active Storage, to respect
    Active Record table name prefix configuration.

    Chedli Bourguiba

  • Fix running db:system:change when the app has no Dockerfile.

    Hartley McGuire

  • In Action Mailer previews, list inline attachments separately from normal
    attachments.

    For example, attachments that were previously listed like

    Attachments: logo.png file1.pdf file2.pdf

    will now be listed like

    Attachments: file1.pdf file2.pdf (Inline: logo.png)

    Christian Schmidt and Jonathan Hefner

  • In mailer preview, only show SMTP-To if it differs from the union of To, Cc and Bcc.

    Christian Schmidt

  • Enable YJIT by default on new applications running Ruby 3.3+.

    This can be disabled by setting Rails.application.config.yjit = false

    Jean Boussier, Rafael Mendonça França

  • In Action Mailer previews, show date from message Date header if present.

    Sampat Badhe

  • Exit with non-zero status when the migration generator fails.

    Katsuhiko YOSHIDA

  • Use numeric UID and GID in Dockerfile template.

    The Dockerfile generated by rails new sets the default user and group
    by name instead of UID:GID. This can cause the following error in Kubernetes:

    container has runAsNonRoot and image has non-numeric user (rails), cannot verify user is non-root
    

    This change sets default user and group by their numeric values.

    Ivan Fedotov

  • Disallow invalid values for rails new options.

    The --database, --asset-pipeline, --css, and --javascript options
    for rails new take different arguments. This change validates them.

    Tony Drake, Akhil G Krishnan, Petrik de Heus

  • Conditionally print $stdout when invoking run_generator.

    In an effort to improve the developer experience when debugging
    generator tests, we add the ability to conditionally print $stdout
    instead of capturing it.

    This allows for calls to binding.irb and puts work as expected.

    RAILS_LOG_TO_STDOUT=true ./bin/test test/generators/actions_test.rb
    

    Steve Polito

  • Remove the option config.public_file_server.enabled from the generators
    for all environments, as the value is the same in all environments.

    Adrian Hirt

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - 7.2.0.rc1

Active Support

  • Fix delegate_missing_to allow_nil: true when called with implict self

    class Person
      delegate_missing_to :address, allow_nil: true
    
      def address
        nil
      end
    
      def berliner?
        city == "Berlin"
      end
    end
    
    Person.new.city # => nil
    Person.new.berliner? # undefined local variable or method `city' for an instance of Person (NameError)
    

    Jean Boussier

Active Model

  • No changes.

Active Record

  • Handle commas in Sqlite3 default function definitions.

    Stephen Margheim

  • Fixes validates_associated raising an exception when configured with a
    singular association and having index_nested_attribute_errors enabled.

    Martin Spickermann

  • The constant ActiveRecord::ImmutableRelation has been deprecated because
    we want to reserve that name for a stronger sense of "immutable relation".
    Please use ActiveRecord::UnmodifiableRelation instead.

    Xavier Noria

Action View

  • No changes.

Action Pack

  • No changes.

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

  • The new bin/rails boot command boots the application and exits. Supports the
    standard -e/--environment options.

    Xavier Noria

- Ruby
Published by rafaelfranca over 1 year ago

https://github.com/rails/rails - v7.2.0.beta3

Action Text

  • Only sanitize content attribute when present in attachments.

    Petrik de Heus

Active Record

  • Add condensed #inspect for ConnectionPool, AbstractAdapter, and
    DatabaseConfig.

    Hartley McGuire

  • Fixed a memory performance issue in Active Record attribute methods definition.

    Jean Boussier

  • Define the new Active Support notification event start_transaction.active_record.
    This event is fired when database transactions or savepoints start, and
    complements transaction.active_record, which is emitted when they finish.
    The payload has the transaction (:transaction) and the connection (:connection).

    Xavier Noria

  • Fix an issue where the IDs reader method did not return expected results
    for preloaded associations in models using composite primary keys.

    Jay Ang

Active Support

  • Add logger as a dependency since it is a bundled gem candidate for Ruby 3.5

    Earlopain

Guides

  • Testing guide: Added a section about the implicit database transaction that
    wraps tests by default.

    Xavier Noria

- Ruby
Published by byroot over 1 year ago

https://github.com/rails/rails - 7.2.0.beta2

Active Support

  • Define Digest::UUID.nil_uuid, which returns the so-called nil UUID.

    Xavier Noria

Active Model

  • No changes.

Active Record

  • The payload of sql.active_record Active Support notifications now has the current transaction in the :transaction key.

    Xavier Noria

  • The payload of transaction.active_record Active Support notifications now has the transaction the event is related to in the :transaction key.

    Xavier Noria

  • Define ActiveRecord::Transaction#uuid, which returns a UUID for the database transaction. This may be helpful when tracing database activity. These UUIDs are generated only on demand.

    Xavier Noria

Action View

  • No changes.

Action Pack

  • Include the HTTP Permissions-Policy on non-HTML Content-Types
    [CVE-2024-28103]

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • Bring ActionCable::Connection::TestCookieJar in alignment with ActionDispatch::Cookies::CookieJar in regards to setting the cookie value.

    Before:

    cookies[:foo] = { value: "bar" }
    puts cookies[:foo] # => { value: "bar" }
    

    After:

    cookies[:foo] = { value: "bar" }
    puts cookies[:foo] # => "bar"
    

    Justin Ko

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Sanitize ActionText HTML ContentAttachment in Trix edit view
    [CVE-2024-32464]

Railties

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.1.3.4

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Include the HTTP Permissions-Policy on non-HTML Content-Types
    [CVE-2024-28103]

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Sanitize ActionText HTML ContentAttachment in Trix edit view
    [CVE-2024-32464]

Railties

  • No changes.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.0.8.4

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Include the HTTP Permissions-Policy on non-HTML Content-Types
    [CVE-2024-28103]

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.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 6.1.7.8

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Include the HTTP Permissions-Policy on non-HTML Content-Types
    [CVE-2024-28103]

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.

- Ruby
Published by jhawthorn over 1 year ago

https://github.com/rails/rails - 7.2.0.beta1

Active Support

  • Support duration type in ActiveSupport::XmlMini.

    heka1024

  • Remove deprecated ActiveSupport::Notifications::Event#children and ActiveSupport::Notifications::Event#parent_of?.

    Rafael Mendonça França

  • Remove deprecated support to call the following methods without passing a deprecator:

    • deprecate
    • deprecate_constant
    • ActiveSupport::Deprecation::DeprecatedObjectProxy.new
    • ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new
    • ActiveSupport::Deprecation::DeprecatedConstantProxy.new
    • assert_deprecated
    • assert_not_deprecated
    • collect_deprecations

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::Deprecation delegation to instance.

    Rafael Mendonça França

  • Remove deprecated SafeBuffer#clone_empty.

    Rafael Mendonça França

  • Remove deprecated #to_default_s from Array, Date, DateTime and Time.

    Rafael Mendonça França

  • Remove deprecated support to passing Dalli::Client instances to MemCacheStore.

    Rafael Mendonça França

  • Remove deprecated config.active_support.use_rfc4122_namespaced_uuids.

    Rafael Mendonça França

  • Remove deprecated config.active_support.remove_deprecated_time_with_zone_name.

    Rafael Mendonça França

  • Remove deprecated config.active_support.disable_to_s_conversion.

    Rafael Mendonça França

  • Remove deprecated support to bolding log text with positional boolean in ActiveSupport::LogSubscriber#color.

    Rafael Mendonça França

  • Remove deprecated constants ActiveSupport::LogSubscriber::CLEAR and ActiveSupport::LogSubscriber::BOLD.

    Rafael Mendonça França

  • Remove deprecated support for config.active_support.cache_format_version = 6.1.

    Rafael Mendonça França

  • Remove deprecated :pool_size and :pool_timeout options for the cache storage.

    Rafael Mendonça França

  • Warn on tests without assertions.

    ActiveSupport::TestCase now warns when tests do not run any assertions.
    This is helpful in detecting broken tests that do not perform intended assertions.

    fatkodima

  • Support hexBinary type in ActiveSupport::XmlMini.

    heka1024

  • Deprecate ActiveSupport::ProxyObject in favor of Ruby's built-in BasicObject.

    Earlopain

  • stub_const now accepts a exists: false parameter to allow stubbing missing constants.

    Jean Boussier

  • Make ActiveSupport::BacktraceCleaner copy filters and silencers on dup and clone.

    Previously the copy would still share the internal silencers and filters array,
    causing state to leak.

    Jean Boussier

  • Updating Astana with Western Kazakhstan TZInfo identifier.

    Damian Nelson

  • Add filename support for ActiveSupport::Logger.logger_outputs_to?.

    logger = Logger.new('/var/log/rails.log')
    ActiveSupport::Logger.logger_outputs_to?(logger, '/var/log/rails.log')
    

    Christian Schmidt

  • Include IPAddr#prefix when serializing an IPAddr using the
    ActiveSupport::MessagePack serializer.

    This change is backward and forward compatible — old payloads can
    still be read, and new payloads will be readable by older versions of Rails.

    Taiki Komaba

  • Add default: support for ActiveSupport::CurrentAttributes.attribute.

    class Current < ActiveSupport::CurrentAttributes
      attribute :counter, default: 0
    end
    

    Sean Doyle

  • Remove deprecated support for the pre-Ruby 2.4 behavior of to_time returning a Time object with local timezone.

    Rafael Mendonça França

  • Deprecate config.active_support.to_time_preserves_timezone.

    Rafael Mendonça França

  • Deprecate DateAndTime::Compatibility.preserve_timezone.

    Rafael Mendonça França

  • Yield instance to Object#with block.

    client.with(timeout: 5_000) do |c|
      c.get("/commits")
    end
    

    Sean Doyle

  • Use logical core count instead of physical core count to determine the
    default number of workers when parallelizing tests.

    Jonathan Hefner

  • Fix Time.now/DateTime.now/Date.today to return results in a system timezone after #travel_to.

    There is a bug in the current implementation of #travel_to:
    it remembers a timezone of its argument, and all stubbed methods start
    returning results in that remembered timezone. However, the expected
    behavior is to return results in a system timezone.

    Aleksei Chernenkov

  • Add ErrorReported#unexpected to report precondition violations.

    For example:

    def edit
      if published?
        Rails.error.unexpected("[BUG] Attempting to edit a published article, that shouldn't be possible")
        return false
      end
      # ...
    end
    

    The above will raise an error in development and test, but only report the error in production.

    Jean Boussier

  • Make the order of read_multi and write_multi notifications for Cache::Store#fetch_multi operations match the order they are executed in.

    Adam Renberg Tamm

  • Make return values of Cache::Store#write consistent.

    The return value was not specified before. Now it returns true on a successful write,
    nil if there was an error talking to the cache backend, and false if the write failed
    for another reason (e.g. the key already exists and unless_exist: true was passed).

    Sander Verdonschot

  • Fix logged cache keys not always matching actual key used by cache action.

    Hartley McGuire

  • Improve error messages of assert_changes and assert_no_changes.

    assert_changes error messages now display objects with .inspect to make it easier
    to differentiate nil from empty strings, strings from symbols, etc.
    assert_no_changes error messages now surface the actual value.

    pcreux

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

    Earlopain

  • Fix BroadcastLogger#dup so that it duplicates the logger's broadcasts.

    Andrew Novoselac

  • Fix issue where bootstrap.rb overwrites the level of a BroadcastLogger's broadcasts.

    Andrew Novoselac

  • Fix compatibility with the semantic_logger gem.

    The semantic_logger gem doesn't behave exactly like stdlib logger in that
    SemanticLogger#level returns a Symbol while stdlib Logger#level returns an Integer.

    This caused the various LogSubscriber classes in Rails to break when assigned a
    SemanticLogger instance.

    Jean Boussier, ojab

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

    Pierre Jambet

  • Implement HashWithIndifferentAccess#to_proc.

    Previously, calling #to_proc on HashWithIndifferentAccess object used inherited #to_proc
    method from the Hash class, which was not able to access values using indifferent keys.

    fatkodima

Active Model

  • Fix a bug where type casting of string to Time and DateTime doesn't
    calculate minus minute value in TZ offset correctly.

    Akira Matsuda

  • Port the type_for_attribute method to Active Model. Classes that include
    ActiveModel::Attributes will now provide this method. This method behaves
    the same for Active Model as it does for Active Record.

    class MyModel
      include ActiveModel::Attributes
    
      attribute :my_attribute, :integer
    end
    
    MyModel.type_for_attribute(:my_attribute) # => #<ActiveModel::Type::Integer ...>
    

    Jonathan Hefner

Active Record

  • Fix inference of association model on nested models with the same demodularized name.

    E.g. with the following setup:

    class Nested::Post < ApplicationRecord
      has_one :post, through: :other
    end
    

    Before, #post would infer the model as Nested::Post, but now it correctly infers Post.

    Joshua Young

  • PostgreSQL Cidr#change? detects the address prefix change.

    Taketo Takashima

  • Change BatchEnumerator#destroy_all to return the total number of affected rows.

    Previously, it always returned nil.

    fatkodima

  • Support touch_all in batches.

    Post.in_batches.touch_all
    

    fatkodima

  • Add support for :if_not_exists and :force options to create_schema.

    fatkodima

  • Fix index_errors having incorrect index in association validation errors.

    lulalala

  • Add index_errors: :nested_attributes_order mode.

    This indexes the association validation errors based on the order received by nested attributes setter, and respects the reject_if configuration. This enables API to provide enough information to the frontend to map the validation errors back to their respective form fields.

    lulalala

  • Add Rails.application.config.active_record.postgresql_adapter_decode_dates to opt out of decoding dates automatically with the postgresql adapter. Defaults to true.

    Joé Dupuis

  • Association option query_constraints is deprecated in favor of foreign_key.

    Nikita Vasilevsky

  • Add ENV["SKIP_TEST_DATABASE_TRUNCATE"] flag to speed up multi-process test runs on large DBs when all tests run within default transaction.

    This cuts ~10s from the test run of HEY when run by 24 processes against the 178 tables, since ~4,000 table truncates can then be skipped.

    DHH

  • Added support for recursive common table expressions.

    Post.with_recursive(
      post_and_replies: [
        Post.where(id: 42),
        Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
      ]
    )
    

    Generates the following SQL:

    WITH RECURSIVE "post_and_replies" AS (
      (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
      UNION ALL
      (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
    )
    SELECT "posts".* FROM "posts"
    

    ClearlyClaire

  • validate_constraint can be called in a change_table block.

    ex:

    change_table :products do |t|
      t.check_constraint "price > discounted_price", name: "price_check", validate: false
      t.validate_check_constraint "price_check"
    end
    

    Cody Cutrer

  • PostgreSQLAdapter now decodes columns of type date to Date instead of string.

    Ex:

    ActiveRecord::Base.connection
         .select_value("select '2024-01-01'::date").class #=> Date
    

    Joé Dupuis

  • Strict loading using :n_plus_one_only does not eagerly load child associations.

    With this change, child associations are no longer eagerly loaded, to
    match intended behavior and to prevent non-deterministic order issues caused
    by calling methods like first or last. As first and last don't cause
    an N+1 by themselves, calling child associations will no longer raise.
    Fixes #49473.

    Before:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first
    # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
    person.posts.first.firm # raises ActiveRecord::StrictLoadingViolationError
    

    After:

    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first # this is 1+1, not N+1
    # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
    person.posts.first.firm # no longer raises
    

    Reid Lynch

  • Allow Sqlite3Adapter to use sqlite3 gem version 2.x.

    Mike Dalessio

  • Allow ActiveRecord::Base#pluck to accept hash values.

    # Before
    Post.joins(:comments).pluck("posts.id", "comments.id", "comments.body")
    
    # After
    Post.joins(:comments).pluck(posts: [:id], comments: [:id, :body])
    

    fatkodima

  • Raise an ActiveRecord::ActiveRecordError error when the MySQL database returns an invalid version string.

    Kevin McPhillips

  • ActiveRecord::Base.transaction now yields an ActiveRecord::Transaction object.

    This allows to register callbacks on it.

    Article.transaction do |transaction|
      article.update(published: true)
      transaction.after_commit do
        PublishNotificationMailer.with(article: article).deliver_later
      end
    end
    

    Jean Boussier

  • Add ActiveRecord::Base.current_transaction.

    Returns the current transaction, to allow registering callbacks on it.

    Article.current_transaction.after_commit do
      PublishNotificationMailer.with(article: article).deliver_later
    end
    

    Jean Boussier

  • Add ActiveRecord.after_all_transactions_commit callback.

    Useful for code that may run either inside or outside a transaction and needs
    to perform work after the state changes have been properly persisted.

    def publish_article(article)
      article.update(published: true)
      ActiveRecord.after_all_transactions_commit do
        PublishNotificationMailer.with(article: article).deliver_later
      end
    end
    

    In the above example, the block is either executed immediately if called outside
    of a transaction, or called after the open transaction is committed.

    If the transaction is rolled back, the block isn't called.

    Jean Boussier

  • Add the ability to ignore counter cache columns until they are backfilled.

    Starting to use counter caches on existing large tables can be troublesome, because the column
    values must be backfilled separately of the column addition (to not lock the table for too long)
    and before the use of :counter_cache (otherwise methods like size/any?/etc, which use
    counter caches internally, can produce incorrect results). People usually use database triggers
    or callbacks on child associations while backfilling before introducing a counter cache
    configuration to the association.

    Now, to safely backfill the column, while keeping the column updated with child records added/removed, use:

    class Comment < ApplicationRecord
      belongs_to :post, counter_cache: { active: false }
    end
    

    While the counter cache is not "active", the methods like size/any?/etc will not use it,
    but get the results directly from the database. After the counter cache column is backfilled, simply
    remove the { active: false } part from the counter cache definition, and it will now be used by the
    mentioned methods.

    fatkodima

  • Retry known idempotent SELECT queries on connection-related exceptions.

    SELECT queries we construct by walking the Arel tree and / or with known model attributes
    are idempotent and can safely be retried in the case of a connection error. Previously,
    adapters such as TrilogyAdapter would raise ActiveRecord::ConnectionFailed: Trilogy::EOFError
    when encountering a connection error mid-request.

    Adrianna Chang

  • Allow association's foreign_key to be composite.

    query_constraints option was the only way to configure a composite foreign key by passing an Array.
    Now it's possible to pass an Array value as foreign_key to achieve the same behavior of an association.

    Nikita Vasilevsky

  • Allow association's primary_key to be composite.

    Association's primary_key can be composite when derived from associated model primary_key or query_constraints.
    Now it's possible to explicitly set it as composite on the association.

    Nikita Vasilevsky

  • Add config.active_record.permanent_connection_checkout setting.

    Controls whether ActiveRecord::Base.connection raises an error, emits a deprecation warning, or neither.

    ActiveRecord::Base.connection checkouts a database connection from the pool and keeps it leased until the end of
    the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
    is available connections.

    This configuration can be used to track down and eliminate code that calls ActiveRecord::Base.connection and
    migrate it to use ActiveRecord::Base.with_connection instead.

    The default behavior remains unchanged, and there is currently no plans to change the default.

    Jean Boussier

  • Add dirties option to uncached.

    This adds a dirties option to ActiveRecord::Base.uncached and
    ActiveRecord::ConnectionAdapters::ConnectionPool#uncached.

    When set to true (the default), writes will clear all query caches belonging to the current thread.
    When set to false, writes to the affected connection pool will not clear any query cache.

    This is needed by Solid Cache so that cache writes do not clear query caches.

    Donal McBreen

  • Deprecate ActiveRecord::Base.connection in favor of .lease_connection.

    The method has been renamed as lease_connection to better reflect that the returned
    connection will be held for the duration of the request or job.

    This deprecation is a soft deprecation, no warnings will be issued and there is no
    current plan to remove the method.

    Jean Boussier

  • Deprecate ActiveRecord::ConnectionAdapters::ConnectionPool#connection.

    The method has been renamed as lease_connection to better reflect that the returned
    connection will be held for the duration of the request or job.

    Jean Boussier

  • Expose a generic fixture accessor for fixture names that may conflict with Minitest.

    assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
    assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
    

    Jean Boussier

  • Using Model.query_constraints with a single non-primary-key column used to raise as expected, but with an
    incorrect error message.

    This has been fixed to raise with a more appropriate error message.

    Joshua Young

  • Fix has_one association autosave setting the foreign key attribute when it is unchanged.

    This behavior is also inconsistent with autosaving belongs_to and can have unintended side effects like raising
    an ActiveRecord::ReadonlyAttributeError when the foreign key attribute is marked as read-only.

    Joshua Young

  • Remove deprecated behavior that would rollback a transaction block when exited using return, break or throw.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_record.commit_transaction_on_non_local_return.

    Rafael Mendonça França

  • Remove deprecated support to pass rewhere to ActiveRecord::Relation#merge.

    Rafael Mendonça França

  • Remove deprecated support to pass deferrable: true to add_foreign_key.

    Rafael Mendonça França

  • Remove deprecated support to quote ActiveSupport::Duration.

    Rafael Mendonça França

  • Remove deprecated #quote_bound_value.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass.

    Rafael Mendonça França

  • Remove deprecated support to apply #connection_pool_list, #active_connections?, #clear_active_connections!,
    #clear_reloadable_connections!, #clear_all_connections! and #flush_idle_connections! to the connections pools
    for the current role when the role argument isn't provided.

    Rafael Mendonça França

  • Remove deprecated #all_connection_pools.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::SchemaCache#data_sources.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ConnectionAdapters::SchemaCache.load_from.

    Rafael Mendonça França

  • Remove deprecated #all_foreign_keys_valid? from database adapters.

    Rafael Mendonça França

  • Remove deprecated support to passing coder and class as second argument to serialize.

    Rafael Mendonça França

  • Remove deprecated support to ActiveRecord::Base#read_attribute(:id) to return the custom primary key value.

    Rafael Mendonça França

  • Remove deprecated TestFixtures.fixture_path.

    Rafael Mendonça França

  • Remove deprecated behavior to support referring to a singular association by its plural name.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_record.allow_deprecated_singular_associations_name.

    Rafael Mendonça França

  • Remove deprecated support to passing SchemaMigration and InternalMetadata classes as arguments to
    ActiveRecord::MigrationContext.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Migration.check_pending method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.runtime method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.runtime= method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::LogSubscriber.reset_runtime method.

    Rafael Mendonça França

  • Remove deprecated support to define explain in the connection adapter with 2 arguments.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::ActiveJobRequiredError.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_active_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_reloadable_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.clear_all_connections!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.flush_idle_connections!.

    Rafael Mendonça França

  • Remove deprecated name argument from ActiveRecord::Base.remove_connection.

    Rafael Mendonça França

  • Remove deprecated support to call alias_attribute with non-existent attribute names.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.active_record.suppress_multiple_database_warning.

    Rafael Mendonça França

  • Add ActiveRecord::Encryption::MessagePackMessageSerializer.

    Serialize data to the MessagePack format, for efficient storage in binary columns.

    The binary encoding requires around 30% less space than the base64 encoding
    used by the default serializer.

    Donal McBreen

  • Add support for encrypting binary columns.

    Ensure encryption and decryption pass Type::Binary::Data around for binary data.

    Previously encrypting binary columns with the ActiveRecord::Encryption::MessageSerializer
    incidentally worked for MySQL and SQLite, but not PostgreSQL.

    Donal McBreen

  • Deprecated ENV["SCHEMA_CACHE"] in favor of schema_cache_path in the database configuration.

    Rafael Mendonça França

  • Add ActiveRecord::Base.with_connection as a shortcut for leasing a connection for a short duration.

    The leased connection is yielded, and for the duration of the block, any call to ActiveRecord::Base.connection
    will yield that same connection.

    This is useful to perform a few database operations without causing a connection to be leased for the
    entire duration of the request or job.

    Jean Boussier

  • Deprecate config.active_record.warn_on_records_fetched_greater_than now that sql.active_record
    notification includes :row_count field.

    Jason Nochlin

  • The fix ensures that the association is joined using the appropriate join type
    (either inner join or left outer join) based on the existing joins in the scope.

    This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.

    Example:

    # `associated` will use `LEFT JOIN` instead of using `JOIN`
    Post.left_joins(:author).where.associated(:author)
    

    Saleh Alhaddad

  • Fix an issue where ActiveRecord::Encryption configurations are not ready before the loading
    of Active Record models, when an application is eager loaded. As a result, encrypted attributes
    could be misconfigured in some cases.

    Maxime Réty

  • Deprecate defining an enum with keyword arguments.

    class Function > ApplicationRecord
      # BAD
      enum color: [:red, :blue],
           type: [:instance, :class]
    
      # GOOD
      enum :color, [:red, :blue]
      enum :type, [:instance, :class]
    end
    

    Hartley McGuire

  • Add config.active_record.validate_migration_timestamps option for validating migration timestamps.

    When set, validates that the timestamp prefix for a migration is no more than a day ahead of
    the timestamp associated with the current time. This is designed to prevent migrations prefixes
    from being hand-edited to future timestamps, which impacts migration generation and other
    migration commands.

    Adrianna Chang

  • Properly synchronize Mysql2Adapter#active? and TrilogyAdapter#active?.

    As well as disconnect! and verify!.

    This generally isn't a big problem as connections must not be shared between
    threads, but is required when running transactional tests or system tests
    and could lead to a SEGV.

    Jean Boussier

  • Support :source_location tag option for query log tags.

    config.active_record.query_log_tags << :source_location
    

    Calculating the caller location is a costly operation and should be used primarily in development
    (note, there is also a config.active_record.verbose_query_logs that serves the same purpose)
    or occasionally on production for debugging purposes.

    fatkodima

  • Add an option to ActiveRecord::Encryption::Encryptor to disable compression.

    Allow compression to be disabled by setting compress: false

      class User
        encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
      end
    

    Donal McBreen

  • Deprecate passing strings to ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename.

    A ActiveRecord::DatabaseConfigurations::DatabaseConfig object should be passed instead.

    Rafael Mendonça França

  • Add row_count field to sql.active_record notification.

    This field returns the amount of rows returned by the query that emitted the notification.

    This metric is useful in cases where one wants to detect queries with big result sets.

    Marvin Bitterlich

  • Consistently raise an ArgumentError when passing an invalid argument to a nested attributes association writer.

    Previously, this would only raise on collection associations and produce a generic error on singular associations.

    Now, it will raise on both collection and singular associations.

    Joshua Young

  • 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 Migrations with versions older than 7.1 validating options given to
    add_reference and t.references.

    Hartley McGuire

  • Add <role>_types class method to ActiveRecord::DelegatedType so that the delegated types can be introspected.

    JP Rosevear

  • Make schema_dump, query_cache, replica and database_tasks configurable via DATABASE_URL.

    This wouldn't always work previously because boolean values would be interpreted as strings.

    e.g. DATABASE_URL=postgres://localhost/foo?schema_dump=false now properly disable dumping the schema
    cache.

    Mike Coutermarsh, Jean Boussier

  • Introduce ActiveRecord::Transactions::ClassMethods#set_callback.

    It is identical to ActiveSupport::Callbacks::ClassMethods#set_callback
    but with support for after_commit and after_rollback callback options.

    Joshua Young

  • Make ActiveRecord::Encryption::Encryptor agnostic of the serialization format used for encrypted data.

    Previously, the encryptor instance only allowed an encrypted value serialized as a String to be passed to the message serializer.

    Now, the encryptor lets the configured message_serializer decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize ActiveRecord::Encryption::Message objects using a type other than String.

    The default ActiveRecord::Encryption::MessageSerializer already ensures that only String objects are passed for deserialization.

    Maxime Réty

  • Fix encrypted_attribute? to take into account context properties passed to encrypts.

    Maxime Réty

  • The object returned by explain now responds to pluck, first,
    last, average, count, maximum, minimum, and sum. Those
    new methods run EXPLAIN on the corresponding queries:

    User.all.explain.count
    # EXPLAIN SELECT COUNT(*) FROM `users`
    # ...
    
    User.all.explain.maximum(:id)
    # EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
    # ...
    

    Petrik de Heus

  • Fixes an issue where validates_associated :on option wasn't respected
    when validating associated records.

    Austen Madden, Alex Ghiculescu, Rafał Brize

  • Allow overriding SQLite defaults from database.yml.

    Any PRAGMA configuration set under the pragmas key in the configuration
    file takes precedence over Rails' defaults, and additional PRAGMAs can be
    set as well.

    database: storage/development.sqlite3
    timeout: 5000
    pragmas:
      journal_mode: off
      temp_store: memory
    

    Stephen Margheim

  • Remove warning message when running SQLite in production, but leave it unconfigured.

    There are valid use cases for running SQLite in production. However, it must be done
    with care, so instead of a warning most users won't see anyway, it's preferable to
    leave the configuration commented out to force them to think about having the database
    on a persistent volume etc.

    Jacopo Beschi, Jean Boussier

  • Add support for generated columns to the SQLite3 adapter.

    Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
    This adds support for those to the SQLite3 adapter.

    create_table :users do |t|
      t.string :name
      t.virtual :name_upper, type: :string, as: 'UPPER(name)'
      t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
    end
    

    Stephen Margheim

  • TrilogyAdapter: ignore host if socket parameter is set.

    This allows to configure a connection on a UNIX socket via DATABASE_URL:

    DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
    

    Jean Boussier

  • Make assert_queries_count, assert_no_queries, assert_queries_match, and
    assert_no_queries_match assertions public.

    To assert the expected number of queries are made, Rails internally uses assert_queries_count and
    assert_no_queries. To assert that specific SQL queries are made, assert_queries_match and
    assert_no_queries_match are used. These assertions can now be used in applications as well.

    class ArticleTest < ActiveSupport::TestCase
      test "queries are made" do
        assert_queries_count(1) { Article.first }
      end
    
      test "creates a foreign key" do
        assert_queries_match(/ADD FOREIGN KEY/i, include_schema: true) do
          @connection.add_foreign_key(:comments, :posts)
        end
      end
    end
    

    Petrik de Heus, fatkodima

  • Fix has_secure_token calls the setter method on initialize.

    Abeid Ahmed

  • When using a DATABASE_URL, allow for a configuration to map the protocol in the URL to a specific database
    adapter. This allows decoupling the adapter the application chooses to use from the database connection details
    set in the deployment environment.

    # ENV['DATABASE_URL'] = "mysql://localhost/example_database"
    config.active_record.protocol_adapters.mysql = "trilogy"
    # will connect to MySQL using the trilogy adapter
    

    Jean Boussier, Kevin McPhillips

  • In cases where MySQL returns warning_count greater than zero, but returns no warnings when
    the SHOW WARNINGS query is executed, ActiveRecord.db_warnings_action proc will still be
    called with a generic warning message rather than silently ignoring the warning(s).

    Kevin McPhillips

  • DatabaseConfigurations#configs_for accepts a symbol in the name parameter.

    Andrew Novoselac

  • 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

  • Make the output of ActiveRecord::Core#inspect configurable.

    By default, calling inspect on a record will yield a formatted string including just the id.

    Post.first.inspect #=> "#<Post id: 1>"
    

    The attributes to be included in the output of inspect can be configured with
    ActiveRecord::Core#attributes_for_inspect.

    Post.attributes_for_inspect = [:id, :title]
    Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
    

    With attributes_for_inspect set to :all, inspect will list all the record's attributes.

    Post.attributes_for_inspect = :all
    Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
    

    In development and test mode, attributes_for_inspect will be set to :all by default.

    You can also call full_inspect to get an inspection with all the attributes.

    The attributes in attribute_for_inspect will also be used for pretty_print.

    Andrew Novoselac

  • Don't mark attributes as changed when reassigned to Float::INFINITY or
    -Float::INFINITY.

    Maicol Bentancor

  • Support the RETURNING clause for MariaDB.

    fatkodima, Nikolay Kondratyev

  • The SQLite3 adapter now implements the supports_deferrable_constraints? contract.

    Allows foreign keys to be deferred by adding the :deferrable key to the foreign_key options.

    add_reference :person, :alias, foreign_key: { deferrable: :deferred }
    add_reference :alias, :person, foreign_key: { deferrable: :deferred }
    

    Stephen Margheim

  • Add the set_constraints helper to PostgreSQL connections.

    Post.create!(user_id: -1) # => ActiveRecord::InvalidForeignKey
    
    Post.transaction do
      Post.connection.set_constraints(:deferred)
      p = Post.create!(user_id: -1)
      u = User.create!
      p.user = u
      p.save!
    end
    

    Cody Cutrer

  • Include ActiveModel::API in ActiveRecord::Base.

    Sean Doyle

  • Ensure #signed_id outputs url_safe strings.

    Jason Meller

  • Add nulls_last and working desc.nulls_first for MySQL.

    Tristan Fellows

  • Allow for more complex hash arguments for order which mimics where in ActiveRecord::Relation.

    Topic.includes(:posts).order(posts: { created_at: :desc })
    

    Myles Boone

Action View

  • Add queries count to template rendering instrumentation.

    # Before
    Completed 200 OK in 3804ms (Views: 41.0ms | ActiveRecord: 33.5ms | Allocations: 112788)
    
    # After
    Completed 200 OK in 3804ms (Views: 41.0ms | ActiveRecord: 33.5ms (2 queries, 1 cached) | Allocations: 112788)
    

    fatkodima

  • Raise ArgumentError if :renderable object does not respond to #render_in.

    Sean Doyle

  • Add the nonce: true option for stylesheet_link_tag helper to support automatic nonce generation for Content Security Policy.

    Works the same way as javascript_include_tag nonce: true does.

    Akhil G Krishnan, AJ Esler

  • Parse ActionView::TestCase#rendered HTML content as Nokogiri::XML::DocumentFragment instead of Nokogiri::XML::Document.

    Sean Doyle

  • Rename ActionView::TestCase::Behavior::Content to ActionView::TestCase::Behavior::RenderedViewContent.

    Make RenderedViewContent inherit from String. Make private API with :nodoc:

    Sean Doyle

  • Deprecate passing nil as value for the model: argument to the form_with method.

    Collin Jilbert

  • Alias field_set_tag helper to fieldset_tag to match <fieldset> element.

    Sean Doyle

  • Deprecate passing content to void elements when using tag.br type tag builders.

    Hartley McGuire

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

    Earlopain

  • Automatically discard the implicit locals injected by collection rendering for template that can't accept them.

    When rendering a collection, two implicit variables are injected, which breaks templates with strict locals.

    Now they are only passed if the template will actually accept them.

    Yasha Krasnou, Jean Boussier

  • Fix @rails/ujs calling start() an extra time when using bundlers.

    Hartley McGuire, Ryunosuke Sato

  • Fix the capture view helper compatibility with HAML and Slim.

    When a blank string was captured in HAML or Slim (and possibly other template engines)
    it would instead return the entire buffer.

    Jean Boussier

  • Updated @rails/ujs files to ignore certain data-* attributes when element is contenteditable.

    This fix was already landed in >= 7.0.4.3, < 7.1.0.
    [CVE-2023-23913]

    Ryunosuke Sato

  • Added validation for HTML tag names in the tag and content_tag helper method.

    The tag and content_tag method now checks that the provided tag name adheres to the HTML
    specification. If an invalid HTML tag name is provided, the method raises an ArgumentError
    with an appropriate error message.

    Examples:

    # Raises ArgumentError: Invalid HTML5 tag name: 12p
    content_tag("12p") # Starting with a number
    
    # Raises ArgumentError: Invalid HTML5 tag name: ""
    content_tag("") # Empty tag name
    
    # Raises ArgumentError: Invalid HTML5 tag name: div/
    tag("div/") # Contains a solidus
    
    # Raises ArgumentError: Invalid HTML5 tag name: "image file"
    tag("image file") # Contains a space
    

    Akhil G Krishnan

Action Pack

  • Fix Mime::Type.parse handling type parameters for HTTP Accept headers.

    Taylor Chaparro

  • Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
    suggested correct location for the missing template.

    Joshua Young

  • Add save_and_open_page helper to IntegrationTest.

    save_and_open_page is a helpful helper to keep a short feedback loop when working on system tests.
    A similar helper with matching signature has been added to integration tests.

    Joé Dupuis

  • Fix a regression in 7.1.3 passing a to: option without a controller when the controller is already defined by a scope.

    Rails.application.routes.draw do
      controller :home do
        get "recent", to: "recent_posts"
      end
    end
    

    Étienne Barrié

  • Request Forgery takes relative paths into account.

    Stefan Wienert

  • Add ".test" as a default allowed host in development to ensure smooth golden-path setup with puma.dev.

    DHH

  • Add allow_browser to set minimum browser versions for the application.

    A browser that's blocked will by default be served the file in public/406-unsupported-browser.html with a HTTP status code of "406 Not Acceptable".

    class ApplicationController < ActionController::Base
      # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting + :has
      allow_browser versions: :modern
    end
    
    class ApplicationController < ActionController::Base
      # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
      allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
    end
    
    class MessagesController < ApplicationController
      # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
      allow_browser versions: { opera: 104, chrome: 119 }, only: :show
    end
    

    DHH

  • Add rate limiting API.

    class SessionsController < ApplicationController
      rate_limit to: 10, within: 3.minutes, only: :create
    end
    
    class SignupsController < ApplicationController
      rate_limit to: 1000, within: 10.seconds,
        by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups!" }, only: :new
    end
    

    DHH, Jean Boussier

  • Add image/svg+xml to the compressible content types of ActionDispatch::Static.

    Georg Ledermann

  • Add instrumentation for ActionController::Live#send_stream.

    Allows subscribing to send_stream events. The event payload contains the filename, disposition, and type.

    Hannah Ramadan

  • Add support for with_routing test helper in ActionDispatch::IntegrationTest.

    Gannon McGibbon

  • Remove deprecated support to set Rails.application.config.action_dispatch.show_exceptions to true and false.

    Rafael Mendonça França

  • Remove deprecated speaker, vibrate, and vr permissions policy directives.

    Rafael Mendonça França

  • Remove deprecated Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type.

    Rafael Mendonça França

  • Deprecate Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality.

    Rafael Mendonça França

  • Remove deprecated comparison between ActionController::Parameters and Hash.

    Rafael Mendonça França

  • Remove deprecated constant AbstractController::Helpers::MissingHelperError.

    Rafael Mendonça França

  • Fix a race condition that could cause a Text file busy - chromedriver
    error with parallel system tests.

    Matt Brictson

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

    Hartley McGuire

  • Remove deprecated constant ActionDispatch::IllegalStateError.

    Rafael Mendonça França

  • Add parameter filter capability for redirect locations.

    It uses the config.filter_parameters to match what needs to be filtered.
    The result would be like this:

    Redirected to http://secret.foo.bar?username=roque&password=[FILTERED]
    

    Fixes #14055.

    Roque Pinel, Trevor Turk, tonytonyjan

Active Job

  • All tests now respect the active_job.queue_adapter config.

    Previously if you had set config.active_job.queue_adapter in your config/application.rb
    or config/environments/test.rb file, the adapter you selected was previously not used consistently
    across all tests. In some tests your adapter would be used, but other tests would use the TestAdapter.

    In Rails 7.2, all tests will respect the queue_adapter config if provided. If no config is provided,
    the TestAdapter will continue to be used.

    See #48585 for more details.

    Alex Ghiculescu

  • Make Active Job transaction aware when used conjointly with Active Record.

    A common mistake with Active Job is to enqueue jobs from inside a transaction,
    causing them to potentially be picked and ran by another process, before the
    transaction is committed, which may result in various errors.

    Topic.transaction do
      topic = Topic.create(...)
      NewTopicNotificationJob.perform_later(topic)
    end
    

    Now Active Job will automatically defer the enqueuing to after the transaction is committed,
    and drop the job if the transaction is rolled back.

    Various queue implementations can choose to disable this behavior, and users can disable it,
    or force it on a per job basis:

    class NewTopicNotificationJob < ApplicationJob
      self.enqueue_after_transaction_commit = :never # or `:always` or `:default`
    end
    

    Jean Boussier, Cristian Bica

  • Do not trigger immediate loading of ActiveJob::Base when loading ActiveJob::TestHelper.

    Maxime Réty

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

    Joshua Young

  • Remove deprecated :exponentially_longer value for the :wait in retry_on.

    Rafael Mendonça França

  • Remove deprecated support to set numeric values to scheduled_at attribute.

    Rafael Mendonça França

  • Deprecate Rails.application.config.active_job.use_big_decimal_serialize.

    Rafael Mendonça França

  • Remove deprecated primitive serializer for BigDecimal arguments.

    Rafael Mendonça França

Action Mailer

  • Remove deprecated params via :args for assert_enqueued_email_with.

    Rafael Mendonça França

  • Remove deprecated config.action_mailer.preview_path.

    Rafael Mendonça França

Action Cable

  • Record ping on every Action Cable message.

    Previously only ping and welcome message types were keeping the connection active.
    Now every Action Cable message updates the pingedAt value, preventing the connection
    from being marked as stale.

    yauhenininjia

  • Add two new assertion methods for Action Cable test cases: assert_has_no_stream
    and assert_has_no_stream_for.

    These methods can be used to assert that a stream has been stopped, e.g. via
    stop_stream or stop_stream_for. They complement the already existing
    assert_has_stream and assert_has_stream_for methods.

    assert_has_no_stream "messages"
    assert_has_no_stream_for User.find(42)
    

    Sebastian Pöll, Junichi Sato

Active Storage

  • Remove deprecated config.active_storage.silence_invalid_content_types_warning.

    Rafael Mendonça França

  • Remove deprecated config.active_storage.replace_on_assign_to_many.

    Rafael Mendonça França

  • Add support for custom key in ActiveStorage::Blob#compose.

    Elvin Efendiev

  • Add image/webp to config.active_storage.web_image_content_types when load_defaults "7.2"
    is set.

    Lewis Buckley

  • Fix JSON-encoding of ActiveStorage::Filename instances.

    Jonathan del Strother

  • Fix N+1 query when fetching preview images for non-image assets.

    Aaron Patterson & Justin Searls

  • Fix all Active Storage database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

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

    Chedli Bourguiba

  • Fix ActiveStorage::Representations::ProxyController to proxy untracked
    variants.

    Chedli Bourguiba

  • When using the preprocessed: true option, avoid enqueuing transform jobs
    for blobs that are not representable.

    Chedli Bourguiba

  • Prevent ActiveStorage::Blob#preview to generate a variant if an empty variation is passed.

    Calls to #url, #key or #download will now use the original preview
    image instead of generating a variant with the exact same dimensions.

    Chedli Bourguiba

  • Process preview image variant when calling ActiveStorage::Preview#processed.

    For example, attached_pdf.preview(:thumb).processed will now immediately
    generate the full-sized preview image and the :thumb variant of it.
    Previously, the :thumb variant would not be generated until a further call
    to e.g. processed.url.

    Chedli Bourguiba and Jonathan Hefner

  • 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 preprocessed: true option for named variants of previewable files.

    Nico Wenterodt

  • Allow accepting service as a proc as well in has_one_attached and has_many_attached.

    Yogesh Khater

Action Mailbox

  • Fix all Action Mailbox database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

Action Text

  • Use includes instead of eager_load for with_all_rich_text.

    Petrik de Heus

  • Delegate ActionText::Content#deconstruct to Nokogiri::XML::DocumentFragment#elements.

    content = ActionText::Content.new <<~HTML
      <h1>Hello, world</h1>
    
      <div>The body</div>
    HTML
    
    content => [h1, div]
    
    assert_pattern { h1 => { content: "Hello, world" } }
    assert_pattern { div => { content: "The body" } }
    

    Sean Doyle

  • Fix all Action Text database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

  • Compile ESM package that can be used directly in the browser as actiontext.esm.js

    Matias Grunberg

  • Fix using actiontext.js with Sprockets.

    Matias Grunberg

  • Upgrade Trix to 2.0.7

    Hartley McGuire

  • Fix using Trix with Sprockets.

    Hartley McGuire

Railties

  • Create a Dev Container Generator that generates a Dev Container setup based on the current configuration
    of the application. Usage:

    bin/rails devcontainer

    Andrew Novoselac

  • Add Rubocop and GitHub Actions to plugin generator.
    This can be skipped using --skip-rubocop and --skip-ci.

    Chris Oliver

  • Remove support for oracle, sqlserver and JRuby specific database adapters from the
    rails new and rails db:system:change commands.

    The supported options are sqlite3, mysql, postgresql and trilogy.

    Andrew Novoselac

  • Add options to bin/rails app:update.

    bin/rails app:update now supports the same generic options that generators do:

    • --force: Accept all changes to existing files
    • --skip: Refuse all changes to existing files
    • --pretend: Don't make any changes
    • --quiet: Don't output all changes made

    Étienne Barrié

  • Implement Rails console commands and helpers with IRB v1.13's extension APIs.

    Rails console users will now see helper, controller, new_session, and app under
    IRB help message's Helper methods category. And reload! command will be displayed under
    the new Rails console commands category.

    Prior to this change, Rails console's commands and helper methods are added through IRB's
    private components and don't show up in its help message, which led to poor discoverability.

    Stan Lo

  • Remove deprecated Rails::Generators::Testing::Behaviour.

    Rafael Mendonça França

  • Remove deprecated find_cmd_and_exec console helper.

    Rafael Mendonça França

  • Remove deprecated Rails.config.enable_dependency_loading.

    Rafael Mendonça França

  • Remove deprecated Rails.application.secrets.

    Rafael Mendonça França

  • Generated Gemfile will include require: "debug/prelude" for the debug gem.

    Requiring debug gem directly automatically activates it, which could introduce
    additional overhead and memory usage even without entering a debugging session.

    By making Bundler require debug/prelude instead, developers can keep their access
    to breakpoint methods like debugger or binding.break, but the debugger won't be
    activated until a breakpoint is hit.

    Stan Lo

  • Skip generating a test job in ci.yml when a new application is generated with the
    --skip-test option.

    Steve Polito

  • Update the .node-version file conditionally generated for new applications to 20.11.1

    Steve Polito

  • Fix sanitizer vendor configuration in 7.1 defaults.

    In apps where rails-html-sanitizer was not eagerly loaded, the sanitizer default could end up
    being Rails::HTML4::Sanitizer when it should be set to Rails::HTML5::Sanitizer.

    Mike Dalessio, Rafael Mendonça França

  • Set action_mailer.default_url_options values in development and test.

    Prior to this commit, new Rails applications would raise ActionView::Template::Error
    if a mailer included a url built with a *_path helper.

    Steve Polito

  • Introduce Rails::Generators::Testing::Assertions#assert_initializer.

    Compliments the existing initializer generator action.

    assert_initializer "mail_interceptors.rb"
    

    Steve Polito

  • Generate a .devcontainer folder and its contents when creating a new app.

    The .devcontainer folder includes everything needed to boot the app and do development in a remote container.

    The container setup includes:

    • A redis container for Kredis, ActionCable etc.
    • A database (SQLite, Postgres, MySQL or MariaDB)
    • A Headless chrome container for system tests
    • Active Storage configured to use the local disk and with preview features working

    If any of these options are skipped in the app setup they will not be included in the container configuration.

    These files can be skipped using the --skip-devcontainer option.

    Andrew Novoselac & Rafael Mendonça França

  • Introduce SystemTestCase#served_by for configuring the System Test application server.

    By default this is localhost. This method allows the host and port to be specified manually.

    class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
      served_by host: "testserver", port: 45678
    end
    

    Andrew Novoselac & Rafael Mendonça França

  • bin/rails test will no longer load files named *_test.rb if they are located in the fixtures folder.

    Edouard Chin

  • Ensure logger tags configured with config.log_tags are still active in request.action_dispatch handlers.

    KJ Tsanaktsidis

  • Setup jemalloc in the default Dockerfile for memory optimization.

    Matt Almeida, Jean Boussier

  • Commented out lines in .railsrc file should not be treated as arguments when using
    rails new generator command. Update ARGVScrubber to ignore text after # symbols.

    Willian Tenfen

  • Skip CSS when generating APIs.

    Ruy Rocha

  • Rails console now indicates application name and the current Rails environment:

    my-app(dev)> # for RAILS_ENV=development
    my-app(test)> # for RAILS_ENV=test
    my-app(prod)> # for RAILS_ENV=production
    my-app(my_env)> # for RAILS_ENV=my_env
    

    The application name is derived from the application's module name from config/application.rb.
    For example, MyApp will displayed as my-app in the prompt.

    Additionally, the environment name will be colorized when the environment is
    development (blue), test (blue), or production (red), if your
    terminal supports it.

    Stan Lo

  • Ensure autoload_paths, autoload_once_paths, eager_load_paths, and
    load_paths only have directories when initialized from engine defaults.

    Previously, files under the app directory could end up there too.

    Takumasa Ochi

  • Prevent unnecessary application reloads in development.

    Previously, some files outside autoload paths triggered unnecessary reloads.
    With this fix, application reloads according to Rails.autoloaders.main.dirs,
    thereby preventing unnecessary reloads.

    Takumasa Ochi

  • Use oven-sh/setup-bun in GitHub CI when generating an app with Bun.

    TangRufus

  • Disable pidfile generation in the production environment.

    Hans Schnedlitz

  • Set config.action_view.annotate_rendered_view_with_filenames to true in
    the development environment.

    Adrian Marin

  • Support the BACKTRACE environment variable to turn off backtrace cleaning.

    Useful for debugging framework code:

    BACKTRACE=1 bin/rails server
    

    Alex Ghiculescu

  • Raise ArgumentError when reading config.x.something with arguments:

    config.x.this_works.this_raises true # raises ArgumentError
    

    Sean Doyle

  • Add default PWA files for manifest and service-worker that are served from app/views/pwa and can be dynamically rendered through ERB. Mount these files explicitly at the root with default routes in the generated routes file.

    DHH

  • Updated system tests to now use headless Chrome by default for the new applications.

    DHH

  • Add GitHub CI files for Dependabot, Brakeman, RuboCop, and running tests by default. Can be skipped with --skip-ci.

    DHH

  • Add Brakeman by default for static analysis of security vulnerabilities. Allow skipping with --skip-brakeman option.

    vipulnsward

  • Add RuboCop with rules from rubocop-rails-omakase by default. Skip with --skip-rubocop.

    DHH and zzak

  • Use bin/rails runner --skip-executor to not wrap the runner script with an
    Executor.

    Ben Sheldon

  • Fix isolated engines to take ActiveRecord::Base.table_name_prefix into consideration.

    This will allow for engine defined models, such as inside Active Storage, to respect
    Active Record table name prefix configuration.

    Chedli Bourguiba

  • Fix running db:system:change when the app has no Dockerfile.

    Hartley McGuire

  • In Action Mailer previews, list inline attachments separately from normal
    attachments.

    For example, attachments that were previously listed like

    Attachments: logo.png file1.pdf file2.pdf

    will now be listed like

    Attachments: file1.pdf file2.pdf (Inline: logo.png)

    Christian Schmidt and Jonathan Hefner

  • In mailer preview, only show SMTP-To if it differs from the union of To, Cc and Bcc.

    Christian Schmidt

  • Enable YJIT by default on new applications running Ruby 3.3+.

    Adds a config/initializers/enable_yjit.rb initializer that enables YJIT
    when running on Ruby 3.3+.

    Jean Boussier

  • In Action Mailer previews, show date from message Date header if present.

    Sampat Badhe

  • Exit with non-zero status when the migration generator fails.

    Katsuhiko YOSHIDA

  • Use numeric UID and GID in Dockerfile template.

    The Dockerfile generated by rails new sets the default user and group
    by name instead of UID:GID. This can cause the following error in Kubernetes:

    container has runAsNonRoot and image has non-numeric user (rails), cannot verify user is non-root
    

    This change sets default user and group by their numeric values.

    Ivan Fedotov

  • Disallow invalid values for rails new options.

    The --database, --asset-pipeline, --css, and --javascript options
    for rails new take different arguments. This change validates them.

    Tony Drake, Akhil G Krishnan, Petrik de Heus

  • Conditionally print $stdout when invoking run_generator.

    In an effort to improve the developer experience when debugging
    generator tests, we add the ability to conditionally print $stdout
    instead of capturing it.

    This allows for calls to binding.irb and puts work as expected.

    RAILS_LOG_TO_STDOUT=true ./bin/test test/generators/actions_test.rb
    

    Steve Polito

  • Remove the option config.public_file_server.enabled from the generators
    for all environments, as the value is the same in all environments.

    Adrian Hirt

- Ruby
Published by rafaelfranca almost 2 years ago

https://github.com/rails/rails - 7.1.3.3

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Upgrade Trix to 2.1.1 to fix CVE-2024-34341.

    Rafael Mendonça França

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 2 years ago

https://github.com/rails/rails - 7.0.8.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Upgrade Trix to 1.3.2 to fix CVE-2024-34341.

    Rafael Mendonça França

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 2 years ago

https://github.com/rails/rails -

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix raise_on_missing_translations not working correctly with the
    translate method in controllers after the patch for CVE-2024-26143.

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.

- Ruby
Published by jhawthorn about 2 years ago

https://github.com/rails/rails - 7.1.3.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix possible XSS vulnerability with the translate method in controllers

    CVE-2024-26143

  • Fix ReDoS in Accept header parsing

    CVE-2024-26142

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.

- Ruby
Published by jhawthorn about 2 years ago

https://github.com/rails/rails - 7.0.8.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix possible XSS vulnerability with the translate method in controllers

    CVE-2024-26143

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Disables the session in ActiveStorage::Blobs::ProxyController
    and ActiveStorage::Representations::ProxyController
    in order to allow caching by default in some CDNs as CloudFlare

    Fixes #44136

    Bruno Prieto

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by jhawthorn about 2 years ago

https://github.com/rails/rails - 6.1.7.7

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Disables the session in ActiveStorage::Blobs::ProxyController
    and ActiveStorage::Representations::ProxyController
    in order to allow caching by default in some CDNs as CloudFlare

    Fixes #44136

    Bruno Prieto

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by jhawthorn about 2 years ago

https://github.com/rails/rails - 7.1.3

Active Support

  • Handle nil backtrace_locations in ActiveSupport::SyntaxErrorProxy.

    Eugene Kenny

  • Fix ActiveSupport::JSON.encode to prevent duplicate keys.

    If the same key exist in both String and Symbol form it could
    lead to the same key being emitted twice.

    Manish Sharma

  • Fix ActiveSupport::Cache::Store#read_multi when using a cache namespace
    and local cache strategy.

    Mark Oleson

  • Fix Time.now/DateTime.now/Date.today to return results in a system timezone after #travel_to.

    There is a bug in the current implementation of #travel_to:
    it remembers a timezone of its argument, and all stubbed methods start
    returning results in that remembered timezone. However, the expected
    behaviour is to return results in a system timezone.

    Aleksei Chernenkov

  • Fix :unless_exist option for MemoryStore#write (et al) when using a
    cache namespace.

    S. Brent Faulkner

  • Fix ActiveSupport::Deprecation to handle blaming generated code.

    Jean Boussier, fatkodima

Active Model

  • No changes.

Active Record

  • Fix Migrations with versions older than 7.1 validating options given to
    add_reference.

    Hartley McGuire

  • Ensure reload sets correct owner for each association.

    Dmytro Savochkin

  • Fix view runtime for controllers with async queries.

    fatkodima

  • Fix load_async to work with query cache.

    fatkodima

  • Fix polymorphic belongs_to to correctly use parent's query_constraints.

    fatkodima

  • Fix Preloader to not generate a query for already loaded association with query_constraints.

    fatkodima

  • Fix multi-database polymorphic preloading with equivalent table names.

    When preloading polymorphic associations, if two models pointed to two
    tables with the same name but located in different databases, the
    preloader would only load one.

    Ari Summer

  • Fix encrypted_attribute? to take into account context properties passed to encrypts.

    Maxime Réty

  • Fix find_by to work correctly in presence of composite primary keys.

    fatkodima

  • Fix async queries sometimes returning a raw result if they hit the query cache.

    ShipPart.async_count could return a raw integer rather than a Promise
    if it found the result in the query cache.

    fatkodima

  • 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 calling async_pluck on a none relation.

    Model.none.async_pluck(:id) was returning a naked value
    instead of a promise.

    Jean Boussier

  • Fix calling load_async on a none relation.

    Model.none.load_async was returning a broken result.

    Lucas Mazza

  • TrilogyAdapter: ignore host if socket parameter is set.

    This allows to configure a connection on a UNIX socket via DATABASE_URL:

    DATABASE_URL=trilogy://does-not-matter/my_db_production?socket=/var/run/mysql.sock
    

    Jean Boussier

  • Fix has_secure_token calls the setter method on initialize.

    Abeid Ahmed

  • Allow using object_id as a database column name.
    It was available before rails 7.1 and may be used as a part of polymorphic relationship to object where object can be any other database record.

    Mikhail Doronin

  • Fix rails db:create:all to not touch databases before they are created.

    fatkodima

Action View

  • Better handle SyntaxError in Action View.

    Mario Caropreso

  • Fix word_wrap with empty string.

    Jonathan Hefner

  • Rename ActionView::TestCase::Behavior::Content to ActionView::TestCase::Behavior::RenderedViewContent.

    Make RenderedViewContent inherit from String. Make private API with :nodoc:.

    Sean Doyle

  • Fix detection of required strict locals.

    Further fix render @collection compatibility with strict locals

    Jean Boussier

Action Pack

  • Fix including Rails.application.routes.url_helpers directly in an
    ActiveSupport::Concern.

    Jonathan Hefner

  • Fix system tests when using a Chrome binary that has been downloaded by
    Selenium.

    Jonathan Hefner

Active Job

  • Do not trigger immediate loading of ActiveJob::Base when loading ActiveJob::TestHelper.

    Maxime Réty

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

    Joshua Young

  • Fix ActiveJob arguments serialization to correctly serialize String subclasses having custom serializers.

    fatkodima

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Fix N+1 query when fetching preview images for non-image assets.

    Aaron Patterson & Justin Searls

  • Fix all Active Storage database related models to respect
    ActiveRecord::Base.table_name_prefix configuration.

    Chedli Bourguiba

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

    Chedli Bourguiba

  • Fix ActiveStorage::Representations::ProxyController to proxy untracked
    variants.

    Chedli Bourguiba

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

    Marc Köhlbrugge

  • When using the preprocessed: true option, avoid enqueuing transform jobs
    for blobs that are not representable.

    Chedli Bourguiba

  • Process preview image variant when calling ActiveStorage::Preview#processed.
    For example, attached_pdf.preview(:thumb).processed will now immediately
    generate the full-sized preview image and the :thumb variant of it.
    Previously, the :thumb variant would not be generated until a further call
    to e.g. processed.url.

    Chedli Bourguiba and Jonathan Hefner

  • 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 preprocessed: true option for named variants of previewable files.

    Nico Wenterodt

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Make sure config.after_routes_loaded hook runs on boot.

    Rafael Mendonça França

  • Fix config.log_level not being respected when using a BroadcastLogger

    Édouard Chin

  • Fix isolated engines to take ActiveRecord::Base.table_name_prefix into consideration.
    This will allow for engine defined models, such as inside Active Storage, to respect
    Active Record table name prefix configuration.

    Chedli Bourguiba

  • The bin/rails app:template command will no longer add potentially unwanted
    gem platforms via bundle lock --add-platform=... commands.

    Jonathan Hefner

- Ruby
Published by rafaelfranca about 2 years ago

https://github.com/rails/rails - 7.1.2

Active Support

  • Fix :expires_in option for RedisCacheStore#write_multi.

    fatkodima

  • Fix deserialization of non-string "purpose" field in Message serializer

    Jacopo Beschi

  • Prevent global cache options being overwritten when setting dynamic options
    inside a ActiveSupport::Cache::Store#fetch block.

    Yasha Krasnou

  • Fix missing require resulting in NoMethodError when running
    bin/rails secrets:show or bin/rails secrets:edit.

    Stephen Ierodiaconou

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

    Jonathan Hefner

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

    Earlopain

  • Fix BroadcastLogger#dup so that it duplicates the logger's broadcasts.

    Andrew Novoselac

  • Fix issue where bootstrap.rb overwrites the level of a BroadcastLogger's broadcasts.

    Andrew Novoselac

  • Fix ActiveSupport::Cache to handle outdated Marshal payload from Rails 6.1 format.

    Active Support's Cache is supposed to treat a Marshal payload that can no longer be
    deserialized as a cache miss. It fail to do so for compressed payload in the Rails 6.1
    legacy format.

    Jean Boussier

  • Fix OrderedOptions#dig for array indexes.

    fatkodima

  • Fix time travel helpers to work when nested using with separate classes.

    fatkodima

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

    fatkodima and Jonathan Hefner

  • Fix compatibility with the semantic_logger gem.

    The semantic_logger gem doesn't behave exactly like stdlib logger in that
    SemanticLogger#level returns a Symbol while stdlib Logger#level returns an Integer.

    This caused the various LogSubscriber classes in Rails to break when assigned a
    SemanticLogger instance.

    Jean Boussier, ojab

Active Model

  • Make ==(other) method of AttributeSet safe.

    Dmitry Pogrebnoy

Active Record

  • 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

  • Prevent marking broken connections as verified.

    Daniel Colson

  • 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

  • Fixed an issue where saving a
    record could innappropriately dup its attributes.

    Jonathan Hefner

  • Dump schema only for a specific db for rollback/up/down tasks for multiple dbs.

    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

  • Re-enable support for using enum with non-column-backed attributes.
    Non-column-backed attributes must be previously declared with an explicit
    type. For example:

    class Post < ActiveRecord::Base
      attribute :topic, :string
      enum topic: %i[science tech engineering math]
    end
    

    Jonathan Hefner

  • Raise on foreign_key: being passed as an array in associations

    Nikita Vasilevsky

  • Return back maximum allowed PostgreSQL table name to 63 characters.

    fatkodima

  • Fix detecting IDENTITY columns for PostgreSQL < 10.

    fatkodima

Action View

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

    Earlopain

  • Automatically discard the implicit locals injected by collection rendering for template that can't accept them

    When rendering a collection, two implicit variables are injected, which breaks templates with strict locals.

    Now they are only passed if the template will actually accept them.

    Yasha Krasnou, Jean Boussier

  • Fix @rails/ujs calling start() an extra time when using bundlers

    Hartley McGuire, Ryunosuke Sato

  • Fix the capture view helper compatibility with HAML and Slim

    When a blank string was captured in HAML or Slim (and possibly other template engines)
    it would instead return the entire buffer.

    Jean Boussier

Action Pack

  • Fix a race condition that could cause a Text file busy - chromedriver
    error with parallel system tests

    Matt Brictson

  • Fix StrongParameters#extract_value to include blank values

    Otherwise composite parameters may not be parsed correctly when one of the
    component is blank.

    fatkodima, Yasha Krasnou, Matthias Eiglsperger

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

    Hartley McGuire

  • Support handling Enumerator for non-buffered responses.

    Zachary Scott

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Compile ESM package that can be used directly in the browser as actiontext.esm.js

    Matias Grunberg

  • Fix using actiontext.js with Sprockets

    Matias Grunberg

  • Upgrade Trix to 2.0.7

    Hartley McGuire

  • Fix using Trix with Sprockets

    Hartley McGuire

Railties

  • Fix running db:system:change when app has no Dockerfile.

    Hartley McGuire

  • If you accessed config.eager_load_paths and friends, later changes to
    config.paths were not reflected in the expected auto/eager load paths.
    Now, they are.

    This bug has been latent since Rails 3.

    Fixes #49629.

    Xavier Noria

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.1.1

Active Support

  • Add support for keyword arguments when delegating calls to custom loggers from ActiveSupport::BroadcastLogger.

    Jenny Shen

  • NumberHelper: handle objects responding to_d.

    fatkodima

  • Fix RedisCacheStore to properly set the TTL when incrementing or decrementing.

    This bug was only impacting Redis server older than 7.0.

    Thomas Countz

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

    Pierre Jambet

Active Model

  • No changes.

Active Record

  • Fix auto populating IDENTITY columns for PostgreSQL.

    fatkodima

  • Fix "ArgumentError: wrong number of arguments (given 3, expected 2)" when
    down migrating rename_table in older migrations.

    fatkodima

  • Do not require the Action Text, Active Storage and Action Mailbox tables
    to be present when running when running test on CI.

    Rafael Mendonça França

Action View

  • Updated @rails/ujs files to ignore certain data-* attributes when element is contenteditable.

    This fix was already landed in >= 7.0.4.3, < 7.1.0.
    [CVE-2023-23913]

    Ryunosuke Sato

Action Pack

  • No changes.

Active Job

  • Don't log enqueuing details when the job wasn't enqueued.

    Dustin Brown

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Ensures the Rails generated Dockerfile uses correct ruby version and matches Gemfile.

    Abhay Nikam

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.1.0

Active Support

  • Fix AS::MessagePack with ENV["RAILS_MAX_THREADS"].

    Jonathan Hefner

  • Add a new public API for broadcasting logs

    This feature existed for a while but was until now a private API.
    Broadcasting log allows to send log message to difference sinks (STDOUT, a file ...) and
    is used by default in the development environment to write logs both on STDOUT and in the
    "development.log" file.

    Basic usage:

    stdout_logger = Logger.new(STDOUT)
    file_logger = Logger.new("development.log")
    broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger, file_logger)
    
    broadcast.info("Hello!") # The "Hello!" message is written on STDOUT and in the log file.
    

    Adding other sink(s) to the broadcast:

    broadcast = ActiveSupport::BroadcastLogger.new
    broadcast.broadcast_to(Logger.new(STDERR))
    

    Remove a sink from the broadcast:

    stdout_logger = Logger.new(STDOUT)
    broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger)
    
    broadcast.stop_broadcasting_to(stdout_logger)
    

    Edouard Chin

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

    Nobuyoshi Nakada, Shouichi Kamiya, Hartley McGuire

  • Use Ruby 3.3 Range#overlap? if available

    Yasuo Honda

  • 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

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

    Yasuo Honda

  • When using cache format version >= 7.1 or a custom serializer, expired and
    version-mismatched cache entries can now be detected without deserializing
    their values.

    Jonathan Hefner

  • Make all cache stores return a boolean for #delete

    Previously the RedisCacheStore#delete would return 1 if the entry
    exists and 0 otherwise. Now it returns true if the entry exists and false
    otherwise, just like the other stores.

    The FileStore would return nil if the entry doesn't exists and returns
    false now as well.

    Petrik de Heus

  • Active Support cache stores now support replacing the default compressor via
    a :compressor option. The specified compressor must respond to deflate
    and inflate. For example:

    module MyCompressor
      def self.deflate(string)
        # compression logic...
      end
    
      def self.inflate(compressed)
        # decompression logic...
      end
    end
    
    config.cache_store = :redis_cache_store, { compressor: MyCompressor }
    

    Jonathan Hefner

  • Active Support cache stores now support a :serializer option. Similar to
    the :coder option, serializers must respond to dump and load. However,
    serializers are only responsible for serializing a cached value, whereas
    coders are responsible for serializing the entire ActiveSupport::Cache::Entry
    instance. Additionally, the output from serializers can be automatically
    compressed, whereas coders are responsible for their own compression.

    Specifying a serializer instead of a coder also enables performance
    optimizations, including the bare string optimization introduced by cache
    format version 7.1.

    The :serializer and :coder options are mutually exclusive. Specifying
    both will raise an ArgumentError.

    Jonathan Hefner

  • Fix ActiveSupport::Inflector.humanize(nil) raising NoMethodError: undefined method `end_with?' for nil:NilClass.

    James Robinson

  • Don't show secrets for ActiveSupport::KeyGenerator#inspect.

    Before:

    ActiveSupport::KeyGenerator.new(secret).inspect
    "#<ActiveSupport::KeyGenerator:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveSupport::KeyGenerator::Aes256Gcm(secret).inspect
    "#<ActiveSupport::KeyGenerator:0x0000000104888038>"
    

    Petrik de Heus

  • Improve error message when EventedFileUpdateChecker is used without a
    compatible version of the Listen gem

    Hartley McGuire

  • Add :report behavior for Deprecation

    Setting config.active_support.deprecation = :report uses the error
    reporter to report deprecation warnings to ActiveSupport::ErrorReporter.

    Deprecations are reported as handled errors, with a severity of :warning.

    Useful to report deprecations happening in production to your bug tracker.

    Étienne Barrié

  • Rename Range#overlaps? to #overlap? and add alias for backwards compatibility

    Christian Schmidt

  • Fix EncryptedConfiguration returning incorrect values for some Hash
    methods

    Hartley McGuire

  • Don't show secrets for MessageEncryptor#inspect.

    Before:

    ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
    "#<ActiveSupport::MessageEncryptor:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
    "#<ActiveSupport::MessageEncryptor:0x0000000104888038>"
    

    Petrik de Heus

  • Don't show contents for EncryptedConfiguration#inspect.

    Before:

    Rails.application.credentials.inspect
    "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8 ... @config={:secret=>\"something secret\"} ... @key_file_contents=\"915e4ea054e011022398dc242\" ...>"
    

    After:

    Rails.application.credentials.inspect
    "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8>"
    

    Petrik de Heus

  • ERB::Util.html_escape_once always returns an html_safe string.

    This method previously maintained the html_safe? property of a string on the return
    value. Because this string has been escaped, however, not marking it as html_safe causes
    entities to be double-escaped.

    As an example, take this view snippet:

    <p><%= html_escape_once("this & that &amp; the other") %></p>
    

    Before this change, that would be double-escaped and render as:

    <p>this &amp;amp; that &amp;amp; the other</p>
    

    After this change, it renders correctly as:

    <p>this &amp; that &amp; the other</p>
    

    Fixes #48256

    Mike Dalessio

  • Deprecate SafeBuffer#clone_empty.

    This method has not been used internally since Rails 4.2.0.

    Mike Dalessio

  • MessageEncryptor, MessageVerifier, and config.active_support.message_serializer
    now accept :message_pack and :message_pack_allow_marshal as serializers.
    These serializers require the msgpack gem
    (>= 1.7.0).

    The Message Pack format can provide improved performance and smaller payload
    sizes. It also supports round-tripping some Ruby types that are not supported
    by JSON. For example:

    verifier = ActiveSupport::MessageVerifier.new("secret")
    data = [{ a: 1 }, { b: 2 }.with_indifferent_access, 1.to_d, Time.at(0, 123)]
    message = verifier.generate(data)
    
    # BEFORE with config.active_support.message_serializer = :json
    verifier.verified(message)
    # => [{"a"=>1}, {"b"=>2}, "1.0", "1969-12-31T18:00:00.000-06:00"]
    verifier.verified(message).map(&:class)
    # => [Hash, Hash, String, String]
    
    # AFTER with config.active_support.message_serializer = :message_pack
    verifier.verified(message)
    # => [{:a=>1}, {"b"=>2}, 0.1e1, 1969-12-31 18:00:00.000123 -0600]
    verifier.verified(message).map(&:class)
    # => [Hash, ActiveSupport::HashWithIndifferentAccess, BigDecimal, Time]
    

    The :message_pack serializer can fall back to deserializing with
    ActiveSupport::JSON when necessary, and the :message_pack_allow_marshal
    serializer can fall back to deserializing with Marshal as well as
    ActiveSupport::JSON. Additionally, the :marshal, :json, and
    :json_allow_marshal serializers can now fall back to deserializing with
    ActiveSupport::MessagePack when necessary. These behaviors ensure old
    messages can still be read so that migration is easier.

    Jonathan Hefner

  • A new 7.1 cache format is available which includes an optimization for
    bare string values such as view fragments.

    The 7.1 cache format is used by default for new apps, and existing apps
    can enable the format by setting config.load_defaults 7.1 or by setting
    config.active_support.cache_format_version = 7.1 in config/application.rb
    or a config/environments/*.rb file.

    Cache entries written using the 6.1 or 7.0 cache formats can be read
    when using the 7.1 format. To perform a rolling deploy of a Rails 7.1
    upgrade, wherein servers that have not yet been upgraded must be able to
    read caches from upgraded servers, leave the cache format unchanged on the
    first deploy, then enable the 7.1 cache format on a subsequent deploy.

    Jonathan Hefner

  • Active Support cache stores can now use a preconfigured serializer based on
    ActiveSupport::MessagePack via the :serializer option:

    config.cache_store = :redis_cache_store, { serializer: :message_pack }
    

    The :message_pack serializer can reduce cache entry sizes and improve
    performance, but requires the msgpack gem
    (>= 1.7.0).

    The :message_pack serializer can read cache entries written by the default
    serializer, and the default serializer can now read entries written by the
    :message_pack serializer. These behaviors make it easy to migrate between
    serializer without invalidating the entire cache.

    Jonathan Hefner

  • Object#deep_dup no longer duplicate named classes and modules.

    Before:

    hash = { class: Object, module: Kernel }
    hash.deep_dup # => {:class=>#<Class:0x00000001063ffc80>, :module=>#<Module:0x00000001063ffa00>}
    

    After:

    hash = { class: Object, module: Kernel }
    hash.deep_dup # => {:class=>Object, :module=>Kernel}
    

    Jean Boussier

  • Consistently raise an ArgumentError if the ActiveSupport::Cache key is blank.

    Joshua Young

  • Deprecate usage of the singleton ActiveSupport::Deprecation.

    All usage of ActiveSupport::Deprecation as a singleton is deprecated, the most common one being
    ActiveSupport::Deprecation.warn. Gem authors should now create their own deprecator (ActiveSupport::Deprecation
    object), and use it to emit deprecation warnings.

    Calling any of the following without specifying a deprecator argument is also deprecated:

    • Module.deprecate
    • deprecate_constant
    • DeprecatedObjectProxy
    • DeprecatedInstanceVariableProxy
    • DeprecatedConstantProxy
    • deprecation-related test assertions

    Use of ActiveSupport::Deprecation.silence and configuration methods like behavior=, disallowed_behavior=,
    disallowed_warnings= should now be aimed at the application's deprecators.

    Rails.application.deprecators.silence do
      # code that emits deprecation warnings
    end
    

    If your gem has a Railtie or Engine, it's encouraged to add your deprecator to the application's deprecators, that
    way the deprecation related configuration options will apply to it as well, e.g.
    config.active_support.report_deprecations set to false in the production environment will also disable your
    deprecator.

    initializer "my_gem.deprecator" do |app|
      app.deprecators[:my_gem] = MyGem.deprecator
    end
    

    Étienne Barrié

  • Add Object#with to set and restore public attributes around a block

    client.timeout # => 5
    client.with(timeout: 1) do
      client.timeout # => 1
    end
    client.timeout # => 5
    

    Jean Boussier

  • Remove deprecated support to generate incorrect RFC 4122 UUIDs when providing a namespace ID that is not one of the
    constants defined on Digest::UUID.

    Rafael Mendonça França

  • Deprecate config.active_support.use_rfc4122_namespaced_uuids.

    Rafael Mendonça França

  • Remove implicit conversion of objects into String by ActiveSupport::SafeBuffer.

    Rafael Mendonça França

  • Remove deprecated active_support/core_ext/range/include_time_with_zone file.

    Rafael Mendonça França

  • Deprecate config.active_support.remove_deprecated_time_with_zone_name.

    Rafael Mendonça França

  • Remove deprecated override of ActiveSupport::TimeWithZone.name.

    Rafael Mendonça França

  • Deprecate config.active_support.disable_to_s_conversion.

    Rafael Mendonça França

  • Remove deprecated option to passing a format to #to_s in Array, Range, Date, DateTime, Time,
    BigDecimal, Float and, Integer.

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::PerThreadRegistry.

    Rafael Mendonça França

  • Remove deprecated override of Enumerable#sum.

    Rafael Mendonça França

  • Deprecated initializing a ActiveSupport::Cache::MemCacheStore with an instance of Dalli::Client.

    Deprecate the undocumented option of providing an already-initialized instance of Dalli::Client to ActiveSupport::Cache::MemCacheStore. Such clients could be configured with unrecognized options, which could lead to unexpected behavior. Instead, provide addresses as documented.

    aledustet

  • Stub Time.new() in TimeHelpers#travel_to

    travel_to Time.new(2004, 11, 24) do
      # Inside the `travel_to` block `Time.new` is stubbed
      assert_equal 2004, Time.new.year
    end
    

    fatkodima

  • Raise ActiveSupport::MessageEncryptor::InvalidMessage from
    ActiveSupport::MessageEncryptor#decrypt_and_verify regardless of cipher.
    Previously, when a MessageEncryptor was using a non-AEAD cipher such as
    AES-256-CBC, a corrupt or tampered message would raise
    ActiveSupport::MessageVerifier::InvalidSignature. Now, all ciphers raise
    the same error:

    encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-gcm")
    message = encryptor.encrypt_and_sign("message")
    encryptor.decrypt_and_verify(message.next)
    # => raises ActiveSupport::MessageEncryptor::InvalidMessage
    
    encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-cbc")
    message = encryptor.encrypt_and_sign("message")
    encryptor.decrypt_and_verify(message.next)
    # BEFORE:
    # => raises ActiveSupport::MessageVerifier::InvalidSignature
    # AFTER:
    # => raises ActiveSupport::MessageEncryptor::InvalidMessage
    

    Jonathan Hefner

  • Support nil original values when using ActiveSupport::MessageVerifier#verify.
    Previously, MessageVerifier#verify did not work with nil original
    values, though both MessageVerifier#verified and
    MessageEncryptor#decrypt_and_verify do:

    encryptor = ActiveSupport::MessageEncryptor.new(secret)
    message = encryptor.encrypt_and_sign(nil)
    
    encryptor.decrypt_and_verify(message)
    # => nil
    
    verifier = ActiveSupport::MessageVerifier.new(secret)
    message = verifier.generate(nil)
    
    verifier.verified(message)
    # => nil
    
    verifier.verify(message)
    # BEFORE:
    # => raises ActiveSupport::MessageVerifier::InvalidSignature
    # AFTER:
    # => nil
    

    Jonathan Hefner

  • Maintain html_safe? on html_safe strings when sliced with slice, slice!, or chr method.

    Previously, html_safe? was only maintained when the html_safe strings were sliced
    with [] method. Now, slice, slice!, and chr methods will maintain html_safe? like [] method.

    string = "<div>test</div>".html_safe
    string.slice(0, 1).html_safe? # => true
    string.slice!(0, 1).html_safe? # => true
    # maintain html_safe? after the slice!
    string.html_safe? # => true
    string.chr.html_safe? # => true
    

    Michael Go

  • Add Object#in? support for open ranges.

    assert Date.today.in?(..Date.tomorrow)
    assert_not Date.today.in?(Date.tomorrow..)
    

    Ignacio Galindo

  • config.i18n.raise_on_missing_translations = true now raises on any missing translation.

    Previously it would only raise when called in a view or controller. Now it will raise
    anytime I18n.t is provided an unrecognised key.

    If you do not want this behaviour, you can customise the i18n exception handler. See the
    upgrading guide or i18n guide for more information.

    Alex Ghiculescu

  • ActiveSupport::CurrentAttributes now raises if a restricted attribute name is used.

    Attributes such as set and reset cannot be used as they clash with the
    CurrentAttributes public API.

    Alex Ghiculescu

  • HashWithIndifferentAccess#transform_keys now takes a Hash argument, just
    as Ruby's Hash#transform_keys does.

    Akira Matsuda

  • delegate now defines method with proper arity when delegating to a Class.
    With this change, it defines faster method (3.5x faster with no argument).
    However, in order to gain this benefit, the delegation target method has to
    be defined before declaring the delegation.

    # This defines 3.5 times faster method than before
    class C
      def self.x() end
      delegate :x, to: :class
    end
    
    class C
      # This works but silently falls back to old behavior because
      # `delegate` cannot find the definition of `x`
      delegate :x, to: :class
      def self.x() end
    end
    

    Akira Matsuda

  • assert_difference message now includes what changed.

    This makes it easier to debug non-obvious failures.

    Before:

    "User.count" didn't change by 32.
    Expected: 1611
      Actual: 1579
    

    After:

    "User.count" didn't change by 32, but by 0.
    Expected: 1611
      Actual: 1579
    

    Alex Ghiculescu

  • Add ability to match exception messages to assert_raises assertion

    Instead of this

    error = assert_raises(ArgumentError) do
      perform_service(param: 'exception')
    end
    assert_match(/incorrect param/i, error.message)
    

    you can now write this

    assert_raises(ArgumentError, match: /incorrect param/i) do
      perform_service(param: 'exception')
    end
    

    fatkodima

  • Add Rails.env.local? shorthand for Rails.env.development? || Rails.env.test?.

    DHH

  • ActiveSupport::Testing::TimeHelpers now accepts named with_usec argument
    to freeze_time, travel, and travel_to methods. Passing true prevents
    truncating the destination time with change(usec: 0).

    KevSlashNull, and serprex

  • ActiveSupport::CurrentAttributes.resets now accepts a method name

    The block API is still the recommended approach, but now both APIs are supported:

    class Current < ActiveSupport::CurrentAttributes
      resets { Time.zone = nil }
      resets :clear_time_zone
    end
    

    Alex Ghiculescu

  • Ensure ActiveSupport::Testing::Isolation::Forking closes pipes

    Previously, Forking.run_in_isolation opened two ends of a pipe. The fork
    process closed the read end, wrote to it, and then terminated (which
    presumably closed the file descriptors on its end). The parent process
    closed the write end, read from it, and returned, never closing the read
    end.

    This resulted in an accumulation of open file descriptors, which could
    cause errors if the limit is reached.

    Sam Bostock

  • Fix Time#change and Time#advance for times around the end of Daylight
    Saving Time.

    Previously, when Time#change or Time#advance constructed a time inside
    the final stretch of Daylight Saving Time (DST), the non-DST offset would
    always be chosen for local times:

    # DST ended just before 2021-11-07 2:00:00 AM in US/Eastern.
    ENV["TZ"] = "US/Eastern"
    
    time = Time.local(2021, 11, 07, 00, 59, 59) + 1
    # => 2021-11-07 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0500
    
    time = Time.local(2021, 11, 06, 01, 00, 00)
    # => 2021-11-06 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(days: 1)
    # => 2021-11-07 01:00:00 -0500
    

    And the DST offset would always be chosen for times with a TimeZone
    object:

    Time.zone = "US/Eastern"
    
    time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
    # => 2021-11-07 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0400
    
    time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
    # => 2021-11-08 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(days: -1)
    # => 2021-11-07 01:00:00 -0400
    

    Now, Time#change and Time#advance will choose the offset that matches
    the original time's offset when possible:

    ENV["TZ"] = "US/Eastern"
    
    time = Time.local(2021, 11, 07, 00, 59, 59) + 1
    # => 2021-11-07 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0400
    
    time = Time.local(2021, 11, 06, 01, 00, 00)
    # => 2021-11-06 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(days: 1)
    # => 2021-11-07 01:00:00 -0400
    
    Time.zone = "US/Eastern"
    
    time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
    # => 2021-11-07 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0500
    
    time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
    # => 2021-11-08 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(days: -1)
    # => 2021-11-07 01:00:00 -0500
    

    Kevin Hall, Takayoshi Nishida, and Jonathan Hefner

  • Fix MemoryStore to preserve entries TTL when incrementing or decrementing

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

    Jean Boussier

  • Rails.error.handle and Rails.error.record filter now by multiple error classes.

    Rails.error.handle(IOError, ArgumentError) do
      1 + '1' # raises TypeError
    end
    1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
    

    Martin Spickermann

  • Class#subclasses and Class#descendants now automatically filter reloaded classes.

    Previously they could return old implementations of reloadable classes that have been
    dereferenced but not yet garbage collected.

    They now automatically filter such classes like DescendantTracker#subclasses and
    DescendantTracker#descendants.

    Jean Boussier

  • Rails.error.report now marks errors as reported to avoid reporting them twice.

    In some cases, users might want to report errors explicitly with some extra context
    before letting it bubble up.

    This also allows to safely catch and report errors outside of the execution context.

    Jean Boussier

  • Add assert_error_reported and assert_no_error_reported

    Allows to easily asserts an error happened but was handled

    report = assert_error_reported(IOError) do
      # ...
    end
    assert_equal "Oops", report.error.message
    assert_equal "admin", report.context[:section]
    assert_equal :warning, report.severity
    assert_predicate report, :handled?
    

    Jean Boussier

  • ActiveSupport::Deprecation behavior callbacks can now receive the
    deprecator instance as an argument. This makes it easier for such callbacks
    to change their behavior based on the deprecator's state. For example,
    based on the deprecator's debug flag.

    3-arity and splat-args callbacks such as the following will now be passed
    the deprecator instance as their third argument:

    • ->(message, callstack, deprecator) { ... }
    • ->(*args) { ... }
    • ->(message, *other_args) { ... }

    2-arity and 4-arity callbacks such as the following will continue to behave
    the same as before:

    • ->(message, callstack) { ... }
    • ->(message, callstack, deprecation_horizon, gem_name) { ... }
    • ->(message, callstack, *deprecation_details) { ... }

    Jonathan Hefner

  • ActiveSupport::Deprecation#disallowed_warnings now affects the instance on
    which it is configured.

    This means that individual ActiveSupport::Deprecation instances can be
    configured with their own disallowed warnings, and the global
    ActiveSupport::Deprecation.disallowed_warnings now only affects the global
    ActiveSupport::Deprecation.warn.

    Before

    ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
    deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
    deprecator.disallowed_warnings = ["bar"]
    
    ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
    ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
    deprecator.warn("foo")                 # => raise ActiveSupport::DeprecationException
    deprecator.warn("bar")                 # => print "DEPRECATION WARNING: bar"
    

    After

    ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
    deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
    deprecator.disallowed_warnings = ["bar"]
    
    ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
    ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
    deprecator.warn("foo")                 # => print "DEPRECATION WARNING: foo"
    deprecator.warn("bar")                 # => raise ActiveSupport::DeprecationException
    

    Note that global ActiveSupport::Deprecation methods such as ActiveSupport::Deprecation.warn
    and ActiveSupport::Deprecation.disallowed_warnings have been deprecated.

    Jonathan Hefner

  • Add italic and underline support to ActiveSupport::LogSubscriber#color

    Previously, only bold text was supported via a positional argument.
    This allows for bold, italic, and underline options to be specified
    for colored logs.

    info color("Hello world!", :red, bold: true, underline: true)
    

    Gannon McGibbon

  • Add String#downcase_first method.

    This method is the corollary of String#upcase_first.

    Mark Schneider

  • thread_mattr_accessor will call .dup.freeze on non-frozen default values.

    This provides a basic level of protection against different threads trying
    to mutate a shared default object.

    Jonathan Hefner

  • Add raise_on_invalid_cache_expiration_time config to ActiveSupport::Cache::Store

    Specifies if an ArgumentError should be raised if Rails.cache fetch or
    write are given an invalid expires_at or expires_in time.

    Options are true, and false. If false, the exception will be reported
    as handled and logged instead. Defaults to true if config.load_defaults >= 7.1.

    Trevor Turk

  • ActiveSupport::Cache:Store#fetch now passes an options accessor to the block.

    It makes possible to override cache options:

    Rails.cache.fetch("3rd-party-token") do |name, options|
      token = fetch_token_from_remote
      # set cache's TTL to match token's TTL
      options.expires_in = token.expires_in
      token
    end
    

    Andrii Gladkyi, Jean Boussier

  • default option of thread_mattr_accessor now applies through inheritance and
    also across new threads.

    Previously, the default value provided was set only at the moment of defining
    the attribute writer, which would cause the attribute to be uninitialized in
    descendants and in other threads.

    Fixes #43312.

    Thierry Deo

  • Redis cache store is now compatible with redis-rb 5.0.

    Jean Boussier

  • Add skip_nil: support to ActiveSupport::Cache::Store#fetch_multi.

    Daniel Alfaro

  • Add quarter method to date/time

    Matt Swanson

  • Fix NoMethodError on custom ActiveSupport::Deprecation behavior.

    ActiveSupport::Deprecation.behavior= was supposed to accept any object
    that responds to call, but in fact its internal implementation assumed that
    this object could respond to arity, so it was restricted to only Proc objects.

    This change removes this arity restriction of custom behaviors.

    Ryo Nakamura

  • Support :url_safe option for MessageEncryptor.

    The MessageEncryptor constructor now accepts a :url_safe option, similar
    to the MessageVerifier constructor. When enabled, this option ensures
    that messages use a URL-safe encoding.

    Jonathan Hefner

  • Add url_safe option to ActiveSupport::MessageVerifier initializer

    ActiveSupport::MessageVerifier.new now takes optional url_safe argument.
    It can generate URL-safe strings by passing url_safe: true.

    verifier = ActiveSupport::MessageVerifier.new(url_safe: true)
    message = verifier.generate(data) # => URL-safe string
    

    This option is false by default to be backwards compatible.

    Shouichi Kamiya

  • Enable connection pooling by default for MemCacheStore and RedisCacheStore.

    If you want to disable connection pooling, set :pool option to false when configuring the cache store:

    config.cache_store = :mem_cache_store, "cache.example.com", pool: false
    

    fatkodima

  • Add force: support to ActiveSupport::Cache::Store#fetch_multi.

    fatkodima

  • Deprecated :pool_size and :pool_timeout options for configuring connection pooling in cache stores.

    Use pool: true to enable pooling with default settings:

    config.cache_store = :redis_cache_store, pool: true
    

    Or pass individual options via :pool option:

    config.cache_store = :redis_cache_store, pool: { size: 10, timeout: 2 }
    

    fatkodima

  • Allow #increment and #decrement methods of ActiveSupport::Cache::Store
    subclasses to set new values.

    Previously incrementing or decrementing an unset key would fail and return
    nil. A default will now be assumed and the key will be created.

    Andrej Blagojević, Eugene Kenny

  • Add skip_nil: support to RedisCacheStore

    Joey Paris

  • ActiveSupport::Cache::MemoryStore#write(name, val, unless_exist:true) now
    correctly writes expired keys.

    Alan Savage

  • ActiveSupport::ErrorReporter now accepts and forward a source: parameter.

    This allow libraries to signal the origin of the errors, and reporters
    to easily ignore some sources.

    Jean Boussier

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

  • Respect ActiveSupport::Logger.new's :formatter keyword argument

    The stdlib Logger::new allows passing a :formatter keyword argument to
    set the logger's formatter. Previously ActiveSupport::Logger.new ignored
    that argument by always setting the formatter to an instance of
    ActiveSupport::Logger::SimpleFormatter.

    Steven Harman

  • Deprecate preserving the pre-Ruby 2.4 behavior of to_time

    With Ruby 2.4+ the default for +to_time+ changed from converting to the
    local system time to preserving the offset of the receiver. At the time Rails
    supported older versions of Ruby so a compatibility layer was added to assist
    in the migration process. From Rails 5.0 new applications have defaulted to
    the Ruby 2.4+ behavior and since Rails 7.0 now only supports Ruby 2.7+
    this compatibility layer can be safely removed.

    To minimize any noise generated the deprecation warning only appears when the
    setting is configured to false as that is the only scenario where the
    removal of the compatibility layer has any effect.

    Andrew White

  • Pathname.blank? only returns true for Pathname.new("")

    Previously it would end up calling Pathname#empty? which returned true
    if the path existed and was an empty directory or file.

    That behavior was unlikely to be expected.

    Jean Boussier

  • Deprecate Notification::Event's #children and #parent_of?

    John Hawthorn

  • Change the default serializer of ActiveSupport::MessageVerifier from
    Marshal to ActiveSupport::JSON when using config.load_defaults 7.1.

    Messages serialized with Marshal can still be read, but new messages will
    be serialized with ActiveSupport::JSON. For more information, see
    https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.

    Saba Kiaei, David Buckley, and Jonathan Hefner

  • Change the default serializer of ActiveSupport::MessageEncryptor from
    Marshal to ActiveSupport::JSON when using config.load_defaults 7.1.

    Messages serialized with Marshal can still be read, but new messages will
    be serialized with ActiveSupport::JSON. For more information, see
    https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.

    Zack Deveau, Martin Gingras, and Jonathan Hefner

  • Add ActiveSupport::TestCase#stub_const to stub a constant for the duration of a yield.

    DHH

  • Fix ActiveSupport::EncryptedConfiguration to be compatible with Psych 4

    Stephen Sugden

  • Improve File.atomic_write error handling

    Daniel Pepper

  • Fix Class#descendants and DescendantsTracker#descendants compatibility with Ruby 3.1.

    The native Class#descendants was reverted prior to Ruby 3.1 release,
    but Class#subclasses was kept, breaking the feature detection.

    Jean Boussier

Active Model

  • Remove change in the typography of user facing error messages.
    For example, “can’t be blank” is again “can't be blank”.

    Rafael Mendonça França

  • Support composite identifiers in to_key

    to_key avoids wrapping #id value into an Array if #id already an array

    Nikita Vasilevsky

  • Add ActiveModel::Conversion.param_delimiter to configure delimiter being used in to_param

    Nikita Vasilevsky

  • undefine_attribute_methods undefines alias attribute methods along with attribute methods.

    Nikita Vasilevsky

  • Error.full_message now strips ":base" from the message.

    zzak

  • Add a load hook for ActiveModel::Model (named active_model) to match the load hook for
    ActiveRecord::Base and allow for overriding aspects of the ActiveModel::Model class.

    Lewis Buckley

  • Improve password length validation in ActiveModel::SecurePassword to consider byte size for BCrypt
    compatibility.

    The previous password length validation only considered the character count, which may not
    accurately reflect the 72-byte size limit imposed by BCrypt. This change updates the validation
    to consider both character count and byte size while keeping the character length validation in place.

    user = User.new(password: "a" * 73)  # 73 characters
    user.valid? # => false
    user.errors[:password] # => ["is too long"]
    
    
    user = User.new(password: "" * 25)  # 25 characters, 75 bytes
    user.valid? # => false
    user.errors[:password] # => ["is too long"]
    

    ChatGPT, Guillermo Iguaran

  • has_secure_password now generates an #{attribute}_salt method that returns the salt
    used to compute the password digest. The salt will change whenever the password is changed,
    so it can be used to create single-use password reset tokens with generates_token_for:

    class User < ActiveRecord::Base
      has_secure_password
    
      generates_token_for :password_reset, expires_in: 15.minutes do
        password_salt&.last(10)
      end
    end
    

    Lázaro Nixon

  • Improve typography of user facing error messages. In English contractions,
    the Unicode APOSTROPHE (U+0027) is now RIGHT SINGLE QUOTATION MARK
    (U+2019). For example, "can't be blank" is now "can’t be blank".

    Jon Dufresne

  • Add class to ActiveModel::MissingAttributeError error message.

    Show which class is missing the attribute in the error message:

    user = User.first
    user.pets.select(:id).first.user_id
    # => ActiveModel::MissingAttributeError: missing attribute 'user_id' for Pet
    

    Petrik de Heus

  • Raise NoMethodError in ActiveModel::Type::Value#as_json to avoid unpredictable
    results.

    Vasiliy Ermolovich

  • Custom attribute types that inherit from Active Model built-in types and do
    not override the serialize method will now benefit from an optimization
    when serializing attribute values for the database.

    For example, with a custom type like the following:

    class DowncasedString < ActiveModel::Type::String
      def cast(value)
        super&.downcase
      end
    end
    
    ActiveRecord::Type.register(:downcased_string, DowncasedString)
    
    class User < ActiveRecord::Base
      attribute :email, :downcased_string
    end
    
    user = User.new(email: "FooBar@example.com")
    

    Serializing the email attribute for the database will be roughly twice as
    fast. More expensive cast operations will likely see greater improvements.

    Jonathan Hefner

  • has_secure_password now supports password challenges via a
    password_challenge accessor and validation.

    A password challenge is a safeguard to verify that the current user is
    actually the password owner. It can be used when changing sensitive model
    fields, such as the password itself. It is different than a password
    confirmation, which is used to prevent password typos.

    When password_challenge is set, the validation checks that the value's
    digest matches the currently persisted password_digest (i.e.
    password_digest_was).

    This allows a password challenge to be done as part of a typical update
    call, just like a password confirmation. It also allows a password
    challenge error to be handled in the same way as other validation errors.

    For example, in the controller, instead of:

    password_params = params.require(:password).permit(
      :password_challenge,
      :password,
      :password_confirmation,
    )
    
    password_challenge = password_params.delete(:password_challenge)
    @password_challenge_failed = !current_user.authenticate(password_challenge)
    
    if !@password_challenge_failed && current_user.update(password_params)
      # ...
    end
    

    You can now write:

    password_params = params.require(:password).permit(
      :password_challenge,
      :password,
      :password_confirmation,
    ).with_defaults(password_challenge: "")
    
    if current_user.update(password_params)
      # ...
    end
    

    And, in the view, instead of checking @password_challenge_failed, you can
    render an error for the password_challenge field just as you would for
    other form fields, including utilizing config.action_view.field_error_proc.

    Jonathan Hefner

  • Support infinite ranges for LengthValidators :in/:within options

    validates_length_of :first_name, in: ..30
    

    fatkodima

  • Add support for beginless ranges to inclusivity/exclusivity validators:

    validates_inclusion_of :birth_date, in: -> { (..Date.today) }
    
    validates_exclusion_of :birth_date, in: -> { (..Date.today) }
    

    Bo Jeanes

  • Make validators accept lambdas without record argument

    # Before
    validates_comparison_of :birth_date, less_than_or_equal_to: ->(_record) { Date.today }
    
    # After
    validates_comparison_of :birth_date, less_than_or_equal_to: -> { Date.today }
    

    fatkodima

  • Fix casting long strings to Date, Time or DateTime

    fatkodima

  • Use different cache namespace for proxy calls

    Models can currently have different attribute bodies for the same method
    names, leading to conflicts. Adding a new namespace :active_model_proxy
    fixes the issue.

    Chris Salzberg

Active Record

  • Remove -shm and -wal SQLite files when rails db:drop is run.

    Niklas Häusele

  • Revert the change to raise an ArgumentError when #accepts_nested_attributes_for is declared more than once for
    an association in the same class.

    The reverted behavior broke the case where the #accepts_nested_attributes_for was defined in a concern and
    where overridden in the class that included the concern.

    Rafael Mendonça França

  • Better naming for unique constraints support.

    Naming unique keys leads to misunderstanding it's a short-hand of unique indexes.
    Just naming it unique constraints is not misleading.

    In Rails 7.1.0.beta1 or before:

    add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_key :sections, name: "unique_section_position"
    

    Now:

    add_unique_constraint :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_constraint :sections, name: "unique_section_position"
    

    Ryuta Kamizono

  • 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

  • Performance tune the SQLite3 adapter connection configuration

    For Rails applications, the Write-Ahead-Log in normal syncing mode with a capped journal size, a healthy shared memory buffer and a shared cache will perform, on average, 2× better.

    Stephen Margheim

  • Allow SQLite3 busy_handler to be configured with simple max number of retries

    Retrying busy connections without delay is a preferred practice for performance-sensitive applications. Add support for a database.yml retries integer, which is used in a simple busy_handler function to retry busy connections without exponential backoff up to the max number of retries.

    Stephen Margheim

  • The SQLite3 adapter now supports supports_insert_returning?

    Implementing the full supports_insert_returning? contract means the SQLite3 adapter supports auto-populated columns (#48241) as well as custom primary keys.

    Stephen Margheim

  • Ensure the SQLite3 adapter handles default functions with the || concatenation operator

    Previously, this default function would produce the static string "'Ruby ' || 'on ' || 'Rails'".
    Now, the adapter will appropriately receive and use "Ruby on Rails".

    change_column_default "test_models", "ruby_on_rails", -> { "('Ruby ' || 'on ' || 'Rails')" }
    

    Stephen Margheim

  • Dump PostgreSQL schemas as part of the schema dump.

    Lachlan Sylvester

  • Encryption now supports support_unencrypted_data being set per-attribute.

    You can now opt out of support_unencrypted_data on a specific encrypted attribute.
    This only has an effect if ActiveRecord::Encryption.config.support_unencrypted_data == true.

    class User < ActiveRecord::Base
      encrypts :name, deterministic: true, support_unencrypted_data: false
      encrypts :email, deterministic: true
    end
    

    Alex Ghiculescu

  • Add instrumentation for Active Record transactions

    Allows subscribing to transaction events for tracking/instrumentation. The event payload contains the connection and the outcome (commit, rollback, restart, incomplete), as well as timing details.

    ActiveSupport::Notifications.subscribe("transaction.active_record") do |event|
      puts "Transaction event occurred!"
      connection = event.payload[:connection]
      puts "Connection: #{connection.inspect}"
    end
    

    Daniel Colson, Ian Candy

  • Support composite foreign keys via migration helpers.

    # Assuming "carts" table has "(shop_id, user_id)" as a primary key.
    
    add_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
    
    remove_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
    foreign_key_exists?(:orders, :carts, primary_key: [:shop_id, :user_id])
    

    fatkodima

  • Adds support for if_not_exists when adding a check constraint.

    add_check_constraint :posts, "post_type IN ('blog', 'comment', 'share')", if_not_exists: true
    

    Cody Cutrer

  • Raise an ArgumentError when #accepts_nested_attributes_for is declared more than once for an association in
    the same class. Previously, the last declaration would silently override the previous one. Overriding in a subclass
    is still allowed.

    Joshua Young

  • Deprecate rewhere argument on #merge.

    The rewhere argument on #mergeis deprecated without replacement and
    will be removed in Rails 7.2.

    Adam Hess

  • Fix unscope is not working in specific case

    Before:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
    
    

    After:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
    

    Fixes #48094.

    Kazuya Hatanaka

  • Change has_secure_token default to on: :initialize

    Change the new default value from on: :create to on: :initialize

    Can be controlled by the config.active_record.generate_secure_token_on
    configuration:

    config.active_record.generate_secure_token_on = :create
    

    Sean Doyle

  • Fix change_column not setting precision: 6 on datetime columns when
    using 7.0+ Migrations and SQLite.

    Hartley McGuire

  • Support composite identifiers in to_key

    to_key avoids wrapping #id value into an Array if #id already an array

    Nikita Vasilevsky

  • Add validation option for enum

    class Contract < ApplicationRecord
      enum :status, %w[in_progress completed], validate: true
    end
    Contract.new(status: "unknown").valid? # => false
    Contract.new(status: nil).valid? # => false
    Contract.new(status: "completed").valid? # => true
    
    class Contract < ApplicationRecord
      enum :status, %w[in_progress completed], validate: { allow_nil: true }
    end
    Contract.new(status: "unknown").valid? # => false
    Contract.new(status: nil).valid? # => true
    Contract.new(status: "completed").valid? # => true
    

    Edem Topuzov, Ryuta Kamizono

  • Allow batching methods to use already loaded relation if available

    Calling batch methods on already loaded relations will use the records previously loaded instead of retrieving
    them from the database again.

    Adam Hess

  • Deprecate read_attribute(:id) returning the primary key if the primary key is not :id.

    Starting in Rails 7.2, read_attribute(:id) will return the value of the id column, regardless of the model's
    primary key. To retrieve the value of the primary key, use #id instead. read_attribute(:id) for composite
    primary key models will now return the value of the id column.

    Adrianna Chang

  • Fix change_table setting datetime precision for 6.1 Migrations

    Hartley McGuire

  • Fix change_column setting datetime precision for 6.1 Migrations

    Hartley McGuire

  • Add ActiveRecord::Base#id_value alias to access the raw value of a record's id column.

    This alias is only provided for models that declare an :id column.

    Adrianna Chang

  • Fix previous change tracking for ActiveRecord::Store when using a column with JSON structured database type

    Before, the methods to access the changes made during the last save #saved_change_to_key?, #saved_change_to_key, and #key_before_last_save did not work if the store was defined as a store_accessor on a column with a JSON structured database type

    Robert DiMartino

  • Fully support NULLS [NOT] DISTINCT for PostgreSQL 15+ indexes.

    Previous work was done to allow the index to be created in a migration, but it was not
    supported in schema.rb. Additionally, the matching for NULLS [NOT] DISTINCT was not
    in the correct order, which could have resulted in inconsistent schema detection.

    Gregory Jones

  • Allow escaping of literal colon characters in sanitize_sql_* methods when named bind variables are used

    Justin Bull

  • Fix #previously_new_record? to return true for destroyed records.

    Before, if a record was created and then destroyed, #previously_new_record? would return true.
    Now, any UPDATE or DELETE to a record is considered a change, and will result in #previously_new_record?
    returning false.

    Adrianna Chang

  • Specify callback in has_secure_token

    class User < ApplicationRecord
      has_secure_token on: :initialize
    end
    
    User.new.token # => "abc123...."
    

    Sean Doyle

  • Fix incrementation of in memory counter caches when associations overlap

    When two associations had a similarly named counter cache column, Active Record
    could sometime increment the wrong one.

    Jacopo Beschi, Jean Boussier

  • Don't show secrets for Active Record's Cipher::Aes256Gcm#inspect.

    Before:

    ActiveRecord::Encryption::Cipher::Aes256Gcm.new(secret).inspect
    "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveRecord::Encryption::Cipher::Aes256Gcm(secret).inspect
    "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038>"
    

    Petrik de Heus

  • Bring back the historical behavior of committing transaction on non-local return.

    Model.transaction do
      model.save
      return
      other_model.save # not executed
    end
    

    Historically only raised errors would trigger a rollback, but in Ruby 2.3, the timeout library
    started using throw to interrupt execution which had the adverse effect of committing open transactions.

    To solve this, in Active Record 6.1 the behavior was changed to instead rollback the transaction as it was safer
    than to potentially commit an incomplete transaction.

    Using return, break or throw inside a transaction block was essentially deprecated from Rails 6.1 onwards.

    However with the release of timeout 0.4.0, Timeout.timeout now raises an error again, and Active Record is able
    to return to its original, less surprising, behavior.

    This historical behavior can now be opt-ed in via:

    Rails.application.config.active_record.commit_transaction_on_non_local_return = true
    

    And is the default for new applications created in Rails 7.1.

    Jean Boussier

  • Deprecate name argument on #remove_connection.

    The name argument is deprecated on #remove_connection without replacement. #remove_connection should be called directly on the class that established the connection.

    Eileen M. Uchitelle

  • Fix has_one through singular building with inverse.

    Allows building of records from an association with a has_one through a
    singular association with inverse. For belongs_to through associations,
    linking the foreign key to the primary key model isn't needed.
    For has_one, we cannot build records due to the association not being mutable.

    Gannon McGibbon

  • Disable database prepared statements when query logs are enabled

    Prepared Statements and Query Logs are incompatible features due to query logs making every query unique.

    zzak, Jean Boussier

  • Support decrypting data encrypted non-deterministically with a SHA1 hash digest.

    This adds a new Active Record encryption option to support decrypting data encrypted
    non-deterministically with a SHA1 hash digest:

    Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
    

    The new option addresses a problem when upgrading from 7.0 to 7.1. Due to a bug in how Active Record
    Encryption was getting initialized, the key provider used for non-deterministic encryption were using
    SHA-1 as its digest class, instead of the one configured globally by Rails via
    Rails.application.config.active_support.key_generator_hash_digest_class.

    Cadu Ribeiro and Jorge Manrubia

  • Added PostgreSQL migration commands for enum rename, add value, and rename value.

    rename_enum and rename_enum_value are reversible. Due to Postgres
    limitation, add_enum_value is not reversible since you cannot delete enum
    values. As an alternative you should drop and recreate the enum entirely.

    rename_enum :article_status, to: :article_state
    
    add_enum_value :article_state, "archived" # will be at the end of existing values
    add_enum_value :article_state, "in review", before: "published"
    add_enum_value :article_state, "approved", after: "in review"
    
    rename_enum_value :article_state, from: "archived", to: "deleted"
    

    Ray Faddis

  • Allow composite primary key to be derived from schema

    Booting an application with a schema that contains composite primary keys
    will not issue warning and won't nilify the ActiveRecord::Base#primary_key value anymore.

    Given a travel_routes table definition and a TravelRoute model like:

    create_table :travel_routes, primary_key: [:origin, :destination], force: true do |t|
      t.string :origin
      t.string :destination
    end
    
    class TravelRoute < ActiveRecord::Base; end
    

    The TravelRoute.primary_key value will be automatically derived to ["origin", "destination"]

    Nikita Vasilevsky

  • Include the connection_pool with exceptions raised from an adapter.

    The connection_pool provides added context such as the connection used
    that led to the exception as well as which role and shard.

    Luan Vieira

  • Support multiple column ordering for find_each, find_in_batches and in_batches.

    When find_each/find_in_batches/in_batches are performed on a table with composite primary keys, ascending or descending order can be selected for each key.

    Person.find_each(order: [:desc, :asc]) do |person|
      person.party_all_night!
    end
    

    Takuya Kurimoto

  • Fix where on association with has_one/has_many polymorphic relations.

    Before:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
    

    Later:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
    

    Lázaro Nixon

  • Assign auto populated columns on Active Record record creation.

    Changes record creation logic to allow for the auto_increment column to be assigned
    immediately after creation regardless of it's relation to the model's primary key.

    The PostgreSQL adapter benefits the most from the change allowing for any number of auto-populated
    columns to be assigned on the object immediately after row insertion utilizing the RETURNING statement.

    Nikita Vasilevsky

  • Use the first key in the shards hash from connected_to for the default_shard.

    Some applications may not want to use :default as a shard name in their connection model. Unfortunately Active Record expects there to be a :default shard because it must assume a shard to get the right connection from the pool manager. Rather than force applications to manually set this, connects_to can infer the default shard name from the hash of shards and will now assume that the first shard is your default.

    For example if your model looked like this:

    class ShardRecord < ApplicationRecord
      self.abstract_class = true
    
      connects_to shards: {
        shard_one: { writing: :shard_one },
        shard_two: { writing: :shard_two }
      }
    

    Then the default_shard for this class would be set to shard_one.

    Fixes: #45390

    Eileen M. Uchitelle

  • Fix mutation detection for serialized attributes backed by binary columns.

    Jean Boussier

  • Add ActiveRecord.disconnect_all! method to immediately close all connections from all pools.

    Jean Boussier

  • Discard connections which may have been left in a transaction.

    There are cases where, due to an error, within_new_transaction may unexpectedly leave a connection in an open transaction. In these cases the connection may be reused, and the following may occur:

    • Writes appear to fail when they actually succeed.
    • Writes appear to succeed when they actually fail.
    • Reads return stale or uncommitted data.

    Previously, the following case was detected:

    • An error is encountered during the transaction, then another error is encountered while attempting to roll it back.

    Now, the following additional cases are detected:

    • An error is encountered just after successfully beginning a transaction.
    • An error is encountered while committing a transaction, then another error is encountered while attempting to roll it back.
    • An error is encountered while rolling back a transaction.

    Nick Dower

  • Active Record query cache now evicts least recently used entries

    By default it only keeps the 100 most recently used queries.

    The cache size can be configured via database.yml

    development:
      adapter: mysql2
      query_cache: 200
    

    It can also be entirely disabled:

    development:
      adapter: mysql2
      query_cache: false
    

    Jean Boussier

  • Deprecate check_pending! in favor of check_all_pending!.

    check_pending! will only check for pending migrations on the current database connection or the one passed in. This has been deprecated in favor of check_all_pending! which will find all pending migrations for the database configurations in a given environment.

    Eileen M. Uchitelle

  • Make increment_counter/decrement_counter accept an amount argument

    Post.increment_counter(:comments_count, 5, by: 3)
    

    fatkodima

  • Add support for Array#intersect? to ActiveRecord::Relation.

    Array#intersect? is only available on Ruby 3.1 or later.

    This allows the Rubocop Style/ArrayIntersect cop to work with ActiveRecord::Relation objects.

    John Harry Kelly

  • The deferrable foreign key can be passed to t.references.

    Hiroyuki Ishii

  • Deprecate deferrable: true option of add_foreign_key.

    deferrable: true is deprecated in favor of deferrable: :immediate, and
    will be removed in Rails 7.2.

    Because deferrable: true and deferrable: :deferred are hard to understand.
    Both true and :deferred are truthy values.
    This behavior is the same as the deferrable option of the add_unique_key method, added in #46192.

    Hiroyuki Ishii

  • AbstractAdapter#execute and #exec_query now clear the query cache

    If you need to perform a read only SQL query without clearing the query
    cache, use AbstractAdapter#select_all.

    Jean Boussier

  • Make .joins / .left_outer_joins work with CTEs.

    For example:

    Post
     .with(commented_posts: Comment.select(:post_id).distinct)
     .joins(:commented_posts)
    #=> WITH (...) SELECT ... INNER JOIN commented_posts on posts.id = commented_posts.post_id
    

    Vladimir Dementyev

  • Add a load hook for ActiveRecord::ConnectionAdapters::Mysql2Adapter
    (named active_record_mysql2adapter) to allow for overriding aspects of the
    ActiveRecord::ConnectionAdapters::Mysql2Adapter class. This makes Mysql2Adapter
    consistent with PostgreSQLAdapter and SQLite3Adapter that already have load hooks.

    fatkodima

  • Introduce adapter for Trilogy database client

    Trilogy is a MySQL-compatible database client. Rails applications can use Trilogy
    by configuring their config/database.yml:

    development:
    adapter: trilogy
    database: blog_development
    pool: 5
    

    Or by using the DATABASE_URL environment variable:

    ENV['DATABASE_URL'] # => "trilogy://localhost/blog_development?pool=5"
    

    Adrianna Chang

  • after_commit callbacks defined on models now execute in the correct order.

    class User < ActiveRecord::Base
      after_commit { puts("this gets called first") }
      after_commit { puts("this gets called second") }
    end
    

    Previously, the callbacks executed in the reverse order. To opt in to the new behaviour:

    config.active_record.run_after_transaction_callbacks_in_order_defined = true
    

    This is the default for new apps.

    Alex Ghiculescu

  • Infer foreign_key when inverse_of is present on has_one and has_many associations.

    has_many :citations, foreign_key: "book1_id", inverse_of: :book
    

    can be simplified to

    has_many :citations, inverse_of: :book
    

    and the foreign_key will be read from the corresponding belongs_to association.

    Daniel Whitney

  • Limit max length of auto generated index names

    Auto generated index names are now limited to 62 bytes, which fits within
    the default index name length limits for MySQL, Postgres and SQLite.

    Any index name over the limit will fallback to the new short format.

    Before (too long):

    index_testings_on_foo_and_bar_and_first_name_and_last_name_and_administrator
    

    After (short format):

    idx_on_foo_bar_first_name_last_name_administrator_5939248142
    

    The short format includes a hash to ensure the name is unique database-wide.

    Mike Coutermarsh

  • Introduce a more stable and optimized Marshal serializer for Active Record models.

    Can be enabled with config.active_record.marshalling_format_version = 7.1.

    Jean Boussier

  • Allow specifying where clauses with column-tuple syntax.

    Querying through #where now accepts a new tuple-syntax which accepts, as
    a key, an array of columns and, as a value, an array of corresponding tuples.
    The key specifies a list of columns, while the value is an array of
    ordered-tuples that conform to the column list.

    For instance:

    # Cpk::Book => Cpk::Book(author_id: integer, number: integer, title: string, revision: integer)
    # Cpk::Book.primary_key => ["author_id", "number"]
    
    book = Cpk::Book.create!(author_id: 1, number: 1)
    Cpk::Book.where(Cpk::Book.primary_key => [[1, 2]]) # => [book]
    
    # Topic => Topic(id: integer, title: string, author_name: string...)
    
    Topic.where([:title, :author_name] => [["The Alchemist", "Paulo Coelho"], ["Harry Potter", "J.K Rowling"]])
    

    Paarth Madan

  • Allow warning codes to be ignore when reporting SQL warnings.

    Active Record config that can ignore warning codes

    # Configure allowlist of warnings that should always be ignored
    config.active_record.db_warnings_ignore = [
      "1062", # MySQL Error 1062: Duplicate entry
    ]
    

    This is supported for the MySQL and PostgreSQL adapters.

    Nick Borromeo

  • Introduce :active_record_fixtures lazy load hook.

    Hooks defined with this name will be run whenever TestFixtures is included
    in a class.

    ActiveSupport.on_load(:active_record_fixtures) do
      self.fixture_paths << "test/fixtures"
    end
    
    klass = Class.new
    klass.include(ActiveRecord::TestFixtures)
    
    klass.fixture_paths # => ["test/fixtures"]
    

    Andrew Novoselac

  • Introduce TestFixtures#fixture_paths.

    Multiple fixture paths can now be specified using the #fixture_paths accessor.
    Apps will continue to have test/fixtures as their one fixture path by default,
    but additional fixture paths can be specified.

    ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
    ActiveSupport::TestCase.fixture_paths << "component2/test/fixtures"
    

    TestFixtures#fixture_path is now deprecated.

    Andrew Novoselac

  • Adds support for deferrable exclude constraints in PostgreSQL.

    By default, exclude constraints in PostgreSQL are checked after each statement.
    This works for most use cases, but becomes a major limitation when replacing
    records with overlapping ranges by using multiple statements.

    exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :immediate
    

    Passing deferrable: :immediate checks constraint after each statement,
    but allows manually deferring the check using SET CONSTRAINTS ALL DEFERRED
    within a transaction. This will cause the excludes to be checked after the transaction.

    It's also possible to change the default behavior from an immediate check
    (after the statement), to a deferred check (after the transaction):

    exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :deferred
    

    Hiroyuki Ishii

  • Respect foreign_type option to delegated_type for {role}_class method.

    Usage of delegated_type with non-conventional {role}_type column names can now be specified with foreign_type option.
    This option is the same as foreign_type as forwarded to the underlying belongs_to association that delegated_type wraps.

    Jason Karns

  • Add support for unique constraints (PostgreSQL-only).

    add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_key :sections, name: "unique_section_position"
    

    See PostgreSQL's Unique Constraints documentation for more on unique constraints.

    By default, unique constraints in PostgreSQL are checked after each statement.
    This works for most use cases, but becomes a major limitation when replacing
    records with unique column by using multiple statements.

    An example of swapping unique columns between records.

    # position is unique column
    old_item = Item.create!(position: 1)
    new_item = Item.create!(position: 2)
    
    Item.transaction do
      old_item.update!(position: 2)
      new_item.update!(position: 1)
    end
    

    Using the default behavior, the transaction would fail when executing the
    first UPDATE statement.

    By passing the :deferrable option to the add_unique_key statement in
    migrations, it's possible to defer this check.

    add_unique_key :items, [:position], deferrable: :immediate
    

    Passing deferrable: :immediate does not change the behaviour of the previous example,
    but allows manually deferring the check using SET CONSTRAINTS ALL DEFERRED within a transaction.
    This will cause the unique constraints to be checked after the transaction.

    It's also possible to adjust the default behavior from an immediate
    check (after the statement), to a deferred check (after the transaction):

    add_unique_key :items, [:position], deferrable: :deferred
    

    If you want to change an existing unique index to deferrable, you can use :using_index
    to create deferrable unique constraints.

    add_unique_key :items, deferrable: :deferred, using_index: "index_items_on_position"
    

    Hiroyuki Ishii

  • Remove deprecated Tasks::DatabaseTasks.schema_file_type.

    Rafael Mendonça França

  • Remove deprecated config.active_record.partial_writes.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base config accessors.

    Rafael Mendonça França

  • Remove the :include_replicas argument from configs_for. Use :include_hidden argument instead.

    Eileen M. Uchitelle

  • Allow applications to lookup a config via a custom hash key.

    If you have registered a custom config or want to find configs where the hash matches a specific key, now you can pass config_key to configs_for. For example if you have a db_config with the key vitess you can look up a database configuration hash by matching that key.

    ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary", config_key: :vitess)
    ActiveRecord::Base.configurations.configs_for(env_name: "development", config_key: :vitess)
    

    Eileen M. Uchitelle

  • Allow applications to register a custom database configuration handler.

    Adds a mechanism for registering a custom handler for cases where you want database configurations to respond to custom methods. This is useful for non-Rails database adapters or tools like Vitess that you may want to configure differently from a standard HashConfig or UrlConfig.

    Given the following database YAML we want the animals db to create a CustomConfig object instead while the primary database will be a UrlConfig:

    development:
      primary:
        url: postgres://localhost/primary
      animals:
        url: postgres://localhost/animals
        custom_config:
          sharded: 1
    

    To register a custom handler first make a class that has your custom methods:

    class CustomConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
      def sharded?
        custom_config.fetch("sharded", false)
      end
    
      private
        def custom_config
          configuration_hash.fetch(:custom_config)
        end
    end
    

    Then register the config in an initializer:

    ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
      next unless config.key?(:custom_config)
      CustomConfig.new(env_name, name, url, config)
    end
    

    When the application is booted, configuration hashes with the :custom_config key will be CustomConfig objects and respond to sharded?. Applications must handle the condition in which Active Record should use their custom handler.

    Eileen M. Uchitelle and John Crepezzi

  • ActiveRecord::Base.serialize no longer uses YAML by default.

    YAML isn't particularly performant and can lead to security issues
    if not used carefully.

    Unfortunately there isn't really any good serializers in Ruby's stdlib
    to replace it.

    The obvious choice would be JSON, which is a fine format for this use case,
    however the JSON serializer in Ruby's stdlib isn't strict enough, as it fallback
    to casting unknown types to strings, which could lead to corrupted data.

    Some third party JSON libraries like Oj have a suitable strict mode.

    So it's preferable that users choose a serializer based on their own constraints.

    The original default can be restored by setting config.active_record.default_column_serializer = YAML.

    Jean Boussier

  • ActiveRecord::Base.serialize signature changed.

    Rather than a single positional argument that accepts two possible
    types of values, serialize now accepts two distinct keyword arguments.

    Before:

    serialize :content, JSON
    serialize :backtrace, Array
    

    After:

    serialize :content, coder: JSON
    serialize :backtrace, type: Array
    

    Jean Boussier

  • YAML columns use YAML.safe_dump if available.

    As of psych 5.1.0, YAML.safe_dump can now apply the same permitted
    types restrictions than YAML.safe_load.

    It's preferable to ensure the payload only use allowed types when we first
    try to serialize it, otherwise you may end up with invalid records in the
    database.

    Jean Boussier

  • ActiveRecord::QueryLogs better handle broken encoding.

    It's not uncommon when building queries with BLOB fields to contain
    binary data. Unless the call carefully encode the string in ASCII-8BIT
    it generally end up being encoded in UTF-8, and QueryLogs would
    end up failing on it.

    ActiveRecord::QueryLogs no longer depend on the query to be properly encoded.

    Jean Boussier

  • Fix a bug where ActiveRecord::Generators::ModelGenerator would not respect create_table_migration template overrides.

    rails g model create_books title:string content:text
    

    will now read from the create_table_migration.rb.tt template in the following locations in order:

    lib/templates/active_record/model/create_table_migration.rb
    lib/templates/active_record/migration/create_table_migration.rb
    

    Spencer Neste

  • ActiveRecord::Relation#explain now accepts options.

    For databases and adapters which support them (currently PostgreSQL
    and MySQL), options can be passed to explain to provide more
    detailed query plan analysis:

    Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)
    

    Reid Lynch

  • Multiple Arel::Nodes::SqlLiteral nodes can now be added together to
    form Arel::Nodes::Fragments nodes. This allows joining several pieces
    of SQL.

    Matthew Draper, Ole Friis

  • ActiveRecord::Base#signed_id raises if called on a new record.

    Previously it would return an ID that was not usable, since it was based on id = nil.

    Alex Ghiculescu

  • Allow SQL warnings to be reported.

    Active Record configs can be set to enable SQL warning reporting.

    # Configure action to take when SQL query produces warning
    config.active_record.db_warnings_action = :raise
    
    # Configure allowlist of warnings that should always be ignored
    config.active_record.db_warnings_ignore = [
      /Invalid utf8mb4 character string/,
      "An exact warning message",
    ]
    

    This is supported for the MySQL and PostgreSQL adapters.

    Adrianna Chang, Paarth Madan

  • Add #regroup query method as a short-hand for .unscope(:group).group(fields)

    Example:

    Post.group(:title).regroup(:author)
    # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
    

    Danielius Visockas

  • PostgreSQL adapter method enable_extension now allows parameter to be [schema_name.]<extension_name>
    if the extension must be installed on another schema.

    Example: enable_extension('heroku_ext.hstore')

    Leonardo Luarte

  • Add :include option to add_index.

    Add support for including non-key columns in indexes for PostgreSQL
    with the INCLUDE parameter.

    add_index(:users, :email, include: [:id, :created_at])
    

    will result in:

    CREATE INDEX index_users_on_email USING btree (email) INCLUDE (id, created_at)
    

    Steve Abrams

  • ActiveRecord::Relation’s #any?, #none?, and #one? methods take an optional pattern
    argument, more closely matching their Enumerable equivalents.

    George Claghorn

  • Add ActiveRecord::Base.normalizes for declaring attribute normalizations.

    An attribute normalization is applied when the attribute is assigned or
    updated, and the normalized value will be persisted to the database. The
    normalization is also applied to the corresponding keyword argument of query
    methods, allowing records to be queried using unnormalized values.

    For example:

    class User < ActiveRecord::Base
      normalizes :email, with: -> email { email.strip.downcase }
      normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
    end
    
    user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
    user.email                  # => "cruise-control@example.com"
    
    user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
    user.email                  # => "cruise-control@example.com"
    user.email_before_type_cast # => "cruise-control@example.com"
    
    User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count         # => 1
    User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
    
    User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")         # => true
    User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
    
    User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"
    

    Jonathan Hefner

  • Hide changes to before_committed! callback behaviour behind flag.

    In #46525, behavior around before_committed! callbacks was changed so that callbacks
    would run on every enrolled record in a transaction, not just the first copy of a record.
    This change in behavior is now controlled by a configuration option,
    config.active_record.before_committed_on_all_records. It will be enabled by default on Rails 7.1.

    Adrianna Chang

  • The namespaced_controller Query Log tag now matches the controller format

    For example, a request processed by NameSpaced::UsersController will now log as:

    :controller # "users"
    :namespaced_controller # "name_spaced/users"
    

    Alex Ghiculescu

  • Return only unique ids from ActiveRecord::Calculations#ids

    Updated ActiveRecord::Calculations#ids to only return the unique ids of the base model
    when using eager_load, preload and includes.

    Post.find_by(id: 1).comments.count
    # => 5
    Post.includes(:comments).where(id: 1).pluck(:id)
    # => [1, 1, 1, 1, 1]
    Post.includes(:comments).where(id: 1).ids
    # => [1]
    

    Joshua Young

  • Stop using LOWER() for case-insensitive queries on citext columns

    Previously, LOWER() was added for e.g. uniqueness validations with
    case_sensitive: false.
    It wasn't mentioned in the documentation that the index without LOWER()
    wouldn't be used in this case.

    Phil Pirozhkov

  • Extract #sync_timezone_changes method in AbstractMysqlAdapter to enable subclasses
    to sync database timezone changes without overriding #raw_execute.

    Adrianna Chang, Paarth Madan

  • Do not write additional new lines when dumping sql migration versions

    This change updates the insert_versions_sql function so that the database insert string containing the current database migration versions does not end with two additional new lines.

    Misha Schwartz

  • Fix composed_of value freezing and duplication.

    Previously composite values exhibited two confusing behaviors:

    • When reading a compositve value it'd NOT be frozen, allowing it to get out of sync with its underlying database
      columns.
    • When writing a compositve value the argument would be frozen, potentially confusing the caller.

    Currently, composite values instantiated based on database columns are frozen (addressing the first issue) and
    assigned compositve values are duplicated and the duplicate is frozen (addressing the second issue).

    Greg Navis

  • Fix redundant updates to the column insensitivity cache

    Fixed redundant queries checking column capability for insensitive
    comparison.

    Phil Pirozhkov

  • Allow disabling methods generated by ActiveRecord.enum.

    Alfred Dominic

  • Avoid validating belongs_to association if it has not changed.

    Previously, when updating a record, Active Record will perform an extra query to check for the presence of
    belongs_to associations (if the presence is configured to be mandatory), even if that attribute hasn't changed.

    Currently, only belongs_to-related columns are checked for presence. It is possible to have orphaned records with
    this approach. To avoid this problem, you need to use a foreign key.

    This behavior can be controlled by configuration:

    config.active_record.belongs_to_required_validates_foreign_key = false
    

    and will be disabled by default with config.load_defaults 7.1.

    fatkodima

  • has_one and belongs_to associations now define a reset_association method
    on the owner model (where association is the name of the association). This
    method unloads the cached associate record, if any, and causes the next access
    to query it from the database.

    George Claghorn

  • Allow per attribute setting of YAML permitted classes (safe load) and unsafe load.

    Carlos Palhares

  • Add a build persistence method

    Provides a wrapper for new, to provide feature parity with creates
    ability to create multiple records from an array of hashes, using the
    same notation as the build method on associations.

    Sean Denny

  • Raise on assignment to readonly attributes

    class Post < ActiveRecord::Base
      attr_readonly :content
    end
    Post.create!(content: "cannot be updated")
    post.content # "cannot be updated"
    post.content = "something else" # => ActiveRecord::ReadonlyAttributeError
    

    Previously, assignment would succeed but silently not write to the database.

    This behavior can be controlled by configuration:

    config.active_record.raise_on_assign_to_attr_readonly = true
    

    and will be enabled by default with config.load_defaults 7.1.

    Alex Ghiculescu, Hartley McGuire

  • Allow unscoping of preload and eager_load associations

    Added the ability to unscope preload and eager_load associations just like
    includes, joins, etc. See ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES
    for the full list of supported unscopable scopes.

    query.unscope(:eager_load, :preload).group(:id).select(:id)
    

    David Morehouse

  • Add automatic filtering of encrypted attributes on inspect

    This feature is enabled by default but can be disabled with

    config.active_record.encryption.add_to_filter_parameters = false
    

    Hartley McGuire

  • Clear locking column on #dup

    This change fixes not to duplicate locking_column like id and timestamps.

    car = Car.create!
    car.touch
    car.lock_version #=> 1
    car.dup.lock_version #=> 0
    

    Shouichi Kamiya, Seonggi Yang, Ryohei UEDA

  • Invalidate transaction as early as possible

    After rescuing a TransactionRollbackError exception Rails invalidates transactions earlier in the flow
    allowing the framework to skip issuing the ROLLBACK statement in more cases.
    Only affects adapters that have savepoint_errors_invalidate_transactions? configured as true,
    which at this point is only applicable to the mysql2 adapter.

    Nikita Vasilevsky

  • Allow configuring columns list to be used in SQL queries issued by an ActiveRecord::Base object

    It is now possible to configure columns list that will be used to build an SQL query clauses when
    updating, deleting or reloading an ActiveRecord::Base object

    class Developer < ActiveRecord::Base
      query_constraints :company_id, :id
    end
    developer = Developer.first.update(name: "Bob")
    # => UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
    

    Nikita Vasilevsky

  • Adds validate to foreign keys and check constraints in schema.rb

    Previously, schema.rb would not record if validate: false had been used when adding a foreign key or check
    constraint, so restoring a database from the schema could result in foreign keys or check constraints being
    incorrectly validated.

    Tommy Graves

  • Adapter #execute methods now accept an allow_retry option. When set to true, the SQL statement will be
    retried, up to the database's configured connection_retries value, upon encountering connection-related errors.

    Adrianna Chang

  • Only trigger after_commit :destroy callbacks when a database row is deleted.

    This prevents after_commit :destroy callbacks from being triggered again
    when destroy is called multiple times on the same record.

    Ben Sheldon

  • Fix ciphertext_for for yet-to-be-encrypted values.

    Previously, ciphertext_for returned the cleartext of values that had not
    yet been encrypted, such as with an unpersisted record:

    Post.encrypts :body
    
    post = Post.create!(body: "Hello")
    post.ciphertext_for(:body)
    # => "{\"p\":\"abc..."
    
    post.body = "World"
    post.ciphertext_for(:body)
    # => "World"
    

    Now, ciphertext_for will always return the ciphertext of encrypted
    attributes:

    Post.encrypts :body
    
    post = Post.create!(body: "Hello")
    post.ciphertext_for(:body)
    # => "{\"p\":\"abc..."
    
    post.body = "World"
    post.ciphertext_for(:body)
    # => "{\"p\":\"xyz..."
    

    Jonathan Hefner

  • Fix a bug where using groups and counts with long table names would return incorrect results.

    Shota Toguchi, Yusaku Ono

  • Fix encryption of column default values.

    Previously, encrypted attributes that used column default values appeared to
    be encrypted on create, but were not:

    Book.encrypts :name
    
    book = Book.create!
    book.name
    # => "<untitled>"
    book.name_before_type_cast
    # => "{\"p\":\"abc..."
    book.reload.name_before_type_cast
    # => "<untitled>"
    

    Now, attributes with column default values are encrypted:

    Book.encrypts :name
    
    book = Book.create!
    book.name
    # => "<untitled>"
    book.name_before_type_cast
    # => "{\"p\":\"abc..."
    book.reload.name_before_type_cast
    # => "{\"p\":\"abc..."
    

    Jonathan Hefner

  • Deprecate delegation from Base to connection_handler.

    Calling Base.clear_all_connections!, Base.clear_active_connections!, Base.clear_reloadable_connections! and Base.flush_idle_connections! is deprecated. Please call these methods on the connection handler directly. In future Rails versions, the delegation from Base to the connection_handler will be removed.

    Eileen M. Uchitelle

  • Allow ActiveRecord::QueryMethods#reselect to receive hash values, similar to ActiveRecord::QueryMethods#select

    Sampat Badhe

  • Validate options when managing columns and tables in migrations.

    If an invalid option is passed to a migration method like create_table and add_column, an error will be raised
    instead of the option being silently ignored. Validation of the options will only be applied for new migrations
    that are created.

    Guo Xiang Tan, George Wambold

  • Update query log tags to use the SQLCommenter format by default. See #46179

    To opt out of SQLCommenter-formatted query log tags, set config.active_record.query_log_tags_format = :legacy. By default, this is set to :sqlcommenter.

    Modulitos and Iheanyi

  • Allow any ERB in the database.yml when creating rake tasks.

    Any ERB can be used in database.yml even if it accesses environment
    configurations.

    Deprecates config.active_record.suppress_multiple_database_warning.

    Eike Send

  • Add table to error for duplicate column definitions.

    If a migration defines duplicate columns for a table, the error message
    shows which table it concerns.

    Petrik de Heus

  • Fix erroneous nil default precision on virtual datetime columns.

    Prior to this change, virtual datetime columns did not have the same
    default precision as regular datetime columns, resulting in the following
    being erroneously equivalent:

    t.virtual :name, type: datetime,                 as: "expression"
    t.virtual :name, type: datetime, precision: nil, as: "expression"
    

    This change fixes the default precision lookup, so virtual and regular
    datetime column default precisions match.

    Sam Bostock

  • Use connection from #with_raw_connection in #quote_string.

    This ensures that the string quoting is wrapped in the reconnect and retry logic
    that #with_raw_connection offers.

    Adrianna Chang

  • Add expires_at option to signed_id.

    Shouichi Kamiya

  • Allow applications to set retry deadline for query retries.

    Building on the work done in #44576 and #44591, we extend the logic that automatically
    reconnects database connections to take into account a timeout limit. We won't retry
    a query if a given amount of time has elapsed since the query was first attempted. This
    value defaults to nil, meaning that all retryable queries are retried regardless of time elapsed,
    but this can be changed via the retry_deadline option in the database config.

    Adrianna Chang

  • Fix a case where the query cache can return wrong values. See #46044

    Aaron Patterson

  • Support MySQL's ssl-mode option for MySQLDatabaseTasks.

    Verifying the identity of the database server requires setting the ssl-mode
    option to VERIFY_CA or VERIFY_IDENTITY. This option was previously ignored
    for MySQL database tasks like creating a database and dumping the structure.

    Petrik de Heus

  • Move ActiveRecord::InternalMetadata to an independent object.

    ActiveRecord::InternalMetadata no longer inherits from ActiveRecord::Base and is now an independent object that should be instantiated with a connection. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: ActiveRecord::Base.connection.schema_migration.

    Eileen M. Uchitelle

  • Deprecate quoting ActiveSupport::Duration as an integer

    Using ActiveSupport::Duration as an interpolated bind parameter in a SQL
    string template is deprecated. To avoid this warning, you should explicitly
    convert the duration to a more specific database type. For example, if you
    want to use a duration as an integer number of seconds:

    Record.where("duration = ?", 1.hour.to_i)
    

    If you want to use a duration as an ISO 8601 string:

    Record.where("duration = ?", 1.hour.iso8601)
    

    Aram Greenman

  • Allow QueryMethods#in_order_of to order by a string column name.

    Post.in_order_of("id", [4,2,3,1]).to_a
    Post.joins(:author).in_order_of("authors.name", ["Bob", "Anna", "John"]).to_a
    

    Igor Kasyanchuk

  • Move ActiveRecord::SchemaMigration to an independent object.

    ActiveRecord::SchemaMigration no longer inherits from ActiveRecord::Base and is now an independent object that should be instantiated with a connection. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: ActiveRecord::Base.connection.schema_migration.

    Eileen M. Uchitelle

  • Deprecate all_connection_pools and make connection_pool_list more explicit.

    Following on #45924 all_connection_pools is now deprecated. connection_pool_list will either take an explicit role or applications can opt into the new behavior by passing :all.

    Eileen M. Uchitelle

  • Fix connection handler methods to operate on all pools.

    active_connections?, clear_active_connections!, clear_reloadable_connections!, clear_all_connections!, and flush_idle_connections! now operate on all pools by default. Previously they would default to using the current_role or :writing role unless specified.

    Eileen M. Uchitelle

  • Allow ActiveRecord::QueryMethods#select to receive hash values.

    Currently, select might receive only raw sql and symbols to define columns and aliases to select.

    With this change we can provide hash as argument, for example:

    Post.joins(:comments).select(posts: [:id, :title, :created_at], comments: [:id, :body, :author_id])
    #=> "SELECT \"posts\".\"id\", \"posts\".\"title\", \"posts\".\"created_at\", \"comments\".\"id\", \"comments\".\"body\", \"comments\".\"author_id\"
    #   FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
    
    Post.joins(:comments).select(posts: { id: :post_id, title: :post_title }, comments: { id: :comment_id, body: :comment_body })
    #=> "SELECT posts.id as post_id, posts.title as post_title, comments.id as comment_id, comments.body as comment_body
    #    FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
    

    Oleksandr Holubenko, Josef Šimánek, Jean Boussier

  • Adapts virtual attributes on ActiveRecord::Persistence#becomes.

    When source and target classes have a different set of attributes adapts
    attributes such that the extra attributes from target are added.

    class Person < ApplicationRecord
    end
    
    class WebUser < Person
      attribute :is_admin, :boolean
      after_initialize :set_admin
    
      def set_admin
        write_attribute(:is_admin, email =~ /@ourcompany\.com$/)
      end
    end
    
    person = Person.find_by(email: "email@ourcompany.com")
    person.respond_to? :is_admin
    # => false
    person.becomes(WebUser).is_admin?
    # => true
    

    Jacopo Beschi, Sampson Crowley

  • Fix ActiveRecord::QueryMethods#in_order_of to include nils, to match the
    behavior of Enumerable#in_order_of.

    For example, Post.in_order_of(:title, [nil, "foo"]) will now include posts
    with nil titles, the same as Post.all.to_a.in_order_of(:title, [nil, "foo"]).

    fatkodima

  • Optimize add_timestamps to use a single SQL statement.

    add_timestamps :my_table
    

    Now results in the following SQL:

    ALTER TABLE "my_table" ADD COLUMN "created_at" datetime(6) NOT NULL, ADD COLUMN "updated_at" datetime(6) NOT NULL
    

    Iliana Hadzhiatanasova

  • Add drop_enum migration command for PostgreSQL

    This does the inverse of create_enum. Before dropping an enum, ensure you have
    dropped columns that depend on it.

    Alex Ghiculescu

  • Adds support for if_exists option when removing a check constraint.

    The remove_check_constraint method now accepts an if_exists option. If set
    to true an error won't be raised if the check constraint doesn't exist.

    Margaret Parsa and Aditya Bhutani

  • find_or_create_by now try to find a second time if it hits a unicity constraint.

    find_or_create_by always has been inherently racy, either creating multiple
    duplicate records or failing with ActiveRecord::RecordNotUnique depending on
    whether a proper unicity constraint was set.

    create_or_find_by was introduced for this use case, however it's quite wasteful
    when the record is expected to exist most of the time, as INSERT require to send
    more data than SELECT and require more work from the database. Also on some
    databases it can actually consume a primary key increment which is undesirable.

    So for case where most of the time the record is expected to exist, find_or_create_by
    can be made race-condition free by re-trying the find if the create failed
    with ActiveRecord::RecordNotUnique. This assumes that the table has the proper
    unicity constraints, if not, find_or_create_by will still lead to duplicated records.

    Jean Boussier, Alex Kitchens

  • Introduce a simpler constructor API for ActiveRecord database adapters.

    Previously the adapter had to know how to build a new raw connection to
    support reconnect, but also expected to be passed an initial already-
    established connection.

    When manually creating an adapter instance, it will now accept a single
    config hash, and only establish the real connection on demand.

    Matthew Draper

  • Avoid redundant SELECT 1 connection-validation query during DB pool
    checkout when possible.

    If the first query run during a request is known to be idempotent, it can be
    used directly to validate the connection, saving a network round-trip.

    Matthew Draper

  • Automatically reconnect broken database connections when safe, even
    mid-request.

    When an error occurs while attempting to run a known-idempotent query, and
    not inside a transaction, it is safe to immediately reconnect to the
    database server and try again, so this is now the default behavior.

    This new default should always be safe -- to support that, it's consciously
    conservative about which queries are considered idempotent -- but if
    necessary it can be disabled by setting the connection_retries connection
    option to 0.

    Matthew Draper

  • Avoid removing a PostgreSQL extension when there are dependent objects.

    Previously, removing an extension also implicitly removed dependent objects. Now, this will raise an error.

    You can force removing the extension:

    disable_extension :citext, force: :cascade
    

    Fixes #29091.

    fatkodima

  • Allow nested functions as safe SQL string

    Michael Siegfried

  • Allow destroy_association_async_job= to be configured with a class string instead of a constant.

    Defers an autoloading dependency between ActiveRecord::Base and ActiveJob::Base
    and moves the configuration of ActiveRecord::DestroyAssociationAsyncJob
    from ActiveJob to ActiveRecord.

    Deprecates ActiveRecord::ActiveJobRequiredError and now raises a NameError
    if the job class is unloadable or an ActiveRecord::ConfigurationError if
    dependent: :destroy_async is declared on an association but there is no job
    class configured.

    Ben Sheldon

  • Fix ActiveRecord::Store to serialize as a regular Hash

    Previously it would serialize as an ActiveSupport::HashWithIndifferentAccess
    which is wasteful and cause problem with YAML safe_load.

    Jean Boussier

  • Add timestamptz as a time zone aware type for PostgreSQL

    This is required for correctly parsing timestamp with time zone values in your database.

    If you don't want this, you can opt out by adding this initializer:

    ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
    

    Alex Ghiculescu

  • Add new ActiveRecord::Base.generates_token_for API.

    Currently, signed_id fulfills the role of generating tokens for e.g.
    resetting a password. However, signed IDs cannot reflect record state, so
    if a token is intended to be single-use, it must be tracked in a database at
    least until it expires.

    With generates_token_for, a token can embed data from a record. When
    using the token to fetch the record, the data from the token and the current
    data from the record will be compared. If the two do not match, the token
    will be treated as invalid, the same as if it had expired. For example:

    class User < ActiveRecord::Base
      has_secure_password
    
      generates_token_for :password_reset, expires_in: 15.minutes do
        # A password's BCrypt salt changes when the password is updated.
        # By embedding (part of) the salt in a token, the token will
        # expire when the password is updated.
        BCrypt::Password.new(password_digest).salt[-10..]
      end
    end
    
    user = User.first
    token = user.generate_token_for(:password_reset)
    
    User.find_by_token_for(:password_reset, token) # => user
    
    user.update!(password: "new password")
    User.find_by_token_for(:password_reset, token) # => nil
    

    Jonathan Hefner

  • Optimize Active Record batching for whole table iterations.

    Previously, in_batches got all the ids and constructed an IN-based query for each batch.
    When iterating over the whole tables, this approach is not optimal as it loads unneeded ids and
    IN queries with lots of items are slow.

    Now, whole table iterations use range iteration (id >= x AND id <= y) by default which can make iteration
    several times faster. E.g., tested on a PostgreSQL table with 10 million records: querying (253s vs 30s),
    updating (288s vs 124s), deleting (268s vs 83s).

    Only whole table iterations use this style of iteration by default. You can disable this behavior by passing use_ranges: false.
    If you iterate over the table and the only condition is, e.g., archived_at: nil (and only a tiny fraction
    of the records are archived), it makes sense to opt in to this approach:

    Project.where(archived_at: nil).in_batches(use_ranges: true) do |relation|
      # do something
    end
    

    See #45414 for more details.

    fatkodima

  • .with query method added. Construct common table expressions with ease and get ActiveRecord::Relation back.

    Post.with(posts_with_comments: Post.where("comments_count > ?", 0))
    # => ActiveRecord::Relation
    # WITH posts_with_comments AS (SELECT * FROM posts WHERE (comments_count > 0)) SELECT * FROM posts
    

    Vlado Cingel

  • Don't establish a new connection if an identical pool exists already.

    Previously, if establish_connection was called on a class that already had an established connection, the existing connection would be removed regardless of whether it was the same config. Now if a pool is found with the same values as the new connection, the existing connection will be returned instead of creating a new one.

    This has a slight change in behavior if application code is depending on a new connection being established regardless of whether it's identical to an existing connection. If the old behavior is desirable, applications should call ActiveRecord::Base#remove_connection before establishing a new one. Calling establish_connection with a different config works the same way as it did previously.

    Eileen M. Uchitelle

  • Update db:prepare task to load schema when an uninitialized database exists, and dump schema after migrations.

    Ben Sheldon

  • Fix supporting timezone awareness for tsrange and tstzrange array columns.

    # In database migrations
    add_column :shops, :open_hours, :tsrange, array: true
    # In app config
    ActiveRecord::Base.time_zone_aware_types += [:tsrange]
    # In the code times are properly converted to app time zone
    Shop.create!(open_hours: [Time.current..8.hour.from_now])
    

    Wojciech Wnętrzak

  • Introduce strategy pattern for executing migrations.

    By default, migrations will use a strategy object that delegates the method
    to the connection adapter. Consumers can implement custom strategy objects
    to change how their migrations run.

    Adrianna Chang

  • Add adapter option disallowing foreign keys

    This adds a new option to be added to database.yml which enables skipping
    foreign key constraints usage even if the underlying database supports them.

    Usage:

    development:
        <<: *default
        database: storage/development.sqlite3
        foreign_keys: false
    

    Paulo Barros

  • Add configurable deprecation warning for singular associations

    This adds a deprecation warning when using the plural name of a singular associations in where.
    It is possible to opt into the new more performant behavior with config.active_record.allow_deprecated_singular_associations_name = false

    Adam Hess

  • Run transactional callbacks on the freshest instance to save a given
    record within a transaction.

    When multiple Active Record instances change the same record within a
    transaction, Rails runs after_commit or after_rollback callbacks for
    only one of them. config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
    was added to specify how Rails chooses which instance receives the
    callbacks. The framework defaults were changed to use the new logic.

    When config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
    is true, transactional callbacks are run on the first instance to save,
    even though its instance state may be stale.

    When it is false, which is the new framework default starting with version
    7.1, transactional callbacks are run on the instances with the freshest
    instance state. Those instances are chosen as follows:

    • In general, run transactional callbacks on the last instance to save a
      given record within the transaction.
    • There are two exceptions:
      • If the record is created within the transaction, then updated by
        another instance, after_create_commit callbacks will be run on the
        second instance. This is instead of the after_update_commit
        callbacks that would naively be run based on that instance’s state.
      • If the record is destroyed within the transaction, then
        after_destroy_commit callbacks will be fired on the last destroyed
        instance, even if a stale instance subsequently performed an update
        (which will have affected 0 rows).

    Cameron Bothner and Mitch Vollebregt

  • Enable strict strings mode for SQLite3Adapter.

    Configures SQLite with a strict strings mode, which disables double-quoted string literals.

    SQLite has some quirks around double-quoted string literals.
    It first tries to consider double-quoted strings as identifier names, but if they don't exist
    it then considers them as string literals. Because of this, typos can silently go unnoticed.
    For example, it is possible to create an index for a non existing column.
    See SQLite documentation for more details.

    If you don't want this behavior, you can disable it via:

    # config/application.rb
    config.active_record.sqlite3_adapter_strict_strings_by_default = false
    

    Fixes #27782.

    fatkodima, Jean Boussier

  • Resolve issue where a relation cache_version could be left stale.

    Previously, when reset was called on a relation object it did not reset the cache_versions
    ivar. This led to a confusing situation where despite having the correct data the relation
    still reported a stale cache_version.

    Usage:

    developers = Developer.all
    developers.cache_version
    
    Developer.update_all(updated_at: Time.now.utc + 1.second)
    
    developers.cache_version # Stale cache_version
    developers.reset
    developers.cache_version # Returns the current correct cache_version
    

    Fixes #45341.

    Austen Madden

  • Add support for exclusion constraints (PostgreSQL-only).

    add_exclusion_constraint :invoices, "daterange(start_date, end_date) WITH &&", using: :gist, name: "invoices_date_overlap"
    remove_exclusion_constraint :invoices, name: "invoices_date_overlap"
    

    See PostgreSQL's CREATE TABLE ... EXCLUDE ... documentation for more on exclusion constraints.

    Alex Robbin

  • change_column_null raises if a non-boolean argument is provided

    Previously if you provided a non-boolean argument, change_column_null would
    treat it as truthy and make your column nullable. This could be surprising, so now
    the input must be either true or false.

    change_column_null :table, :column, true # good
    change_column_null :table, :column, false # good
    change_column_null :table, :column, from: true, to: false # raises (previously this made the column nullable)
    

    Alex Ghiculescu

  • Enforce limit on table names length.

    Fixes #45130.

    fatkodima

  • Adjust the minimum MariaDB version for check constraints support.

    Eddie Lebow

  • Fix Hstore deserialize regression.

    edsharp

  • Add validity for PostgreSQL indexes.

    connection.index_exists?(:users, :email, valid: true)
    connection.indexes(:users).select(&:valid?)
    

    fatkodima

  • Fix eager loading for models without primary keys.

    Anmol Chopra, Matt Lawrence, and Jonathan Hefner

  • Avoid validating a unique field if it has not changed and is backed by a unique index.

    Previously, when saving a record, Active Record will perform an extra query to check for the
    uniqueness of each attribute having a uniqueness validation, even if that attribute hasn't changed.
    If the database has the corresponding unique index, then this validation can never fail for persisted
    records, and we could safely skip it.

    fatkodima

  • Stop setting sql_auto_is_null

    Since version 5.5 the default has been off, we no longer have to manually turn it off.

    Adam Hess

  • Fix touch to raise an error for readonly columns.

    fatkodima

  • Add ability to ignore tables by regexp for SQL schema dumps.

    ActiveRecord::SchemaDumper.ignore_tables = [/^_/]
    

    fatkodima

  • Avoid queries when performing calculations on contradictory relations.

    Previously calculations would make a query even when passed a
    contradiction, such as User.where(id: []).count. We no longer perform a
    query in that scenario.

    This applies to the following calculations: count, sum, average,
    minimum and maximum

    Luan Vieira, John Hawthorn and Daniel Colson

  • Allow using aliased attributes with insert_all/upsert_all.

    class Book < ApplicationRecord
      alias_attribute :title, :name
    end
    
    Book.insert_all [{ title: "Remote", author_id: 1 }], returning: :title
    

    fatkodima

  • Support encrypted attributes on columns with default db values.

    This adds support for encrypted attributes defined on columns with default values.
    It will encrypt those values at creation time. Before, it would raise an
    error unless config.active_record.encryption.support_unencrypted_data was true.

    Jorge Manrubia and Dima Fatko

  • Allow overriding reading_request? in DatabaseSelector::Resolver

    The default implementation checks if a request is a get? or head?,
    but you can now change it to anything you like. If the method returns true,
    Resolver#read gets called meaning the request could be served by the
    replica database.

    Alex Ghiculescu

  • Remove ActiveRecord.legacy_connection_handling.

    Eileen M. Uchitelle

  • rails db:schema:{dump,load} now checks ENV["SCHEMA_FORMAT"] before config

    Since rails db:structure:{dump,load} was deprecated there wasn't a simple
    way to dump a schema to both SQL and Ruby formats. You can now do this with
    an environment variable. For example:

    SCHEMA_FORMAT=sql rake db:schema:dump
    

    Alex Ghiculescu

  • Fixed MariaDB default function support.

    Defaults would be written wrong in "db/schema.rb" and not work correctly
    if using db:schema:load. Further more the function name would be
    added as string content when saving new records.

    kaspernj

  • Add active_record.destroy_association_async_batch_size configuration

    This allows applications to specify the maximum number of records that will
    be destroyed in a single background job by the dependent: :destroy_async
    association option. By default, the current behavior will remain the same:
    when a parent record is destroyed, all dependent records will be destroyed
    in a single background job. If the number of dependent records is greater
    than this configuration, the records will be destroyed in multiple
    background jobs.

    Nick Holden

  • Fix remove_foreign_key with :if_exists option when foreign key actually exists.

    fatkodima

  • Remove --no-comments flag in structure dumps for PostgreSQL

    This broke some apps that used custom schema comments. If you don't want
    comments in your structure dump, you can use:

    ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
    

    Alex Ghiculescu

  • Reduce the memory footprint of fixtures accessors.

    Until now fixtures accessors were eagerly defined using define_method.
    So the memory usage was directly dependent of the number of fixtures and
    test suites.

    Instead fixtures accessors are now implemented with method_missing,
    so they incur much less memory and CPU overhead.

    Jean Boussier

  • Fix config.active_record.destroy_association_async_job configuration

    config.active_record.destroy_association_async_job should allow
    applications to specify the job that will be used to destroy associated
    records in the background for has_many associations with the
    dependent: :destroy_async option. Previously, that was ignored, which
    meant the default ActiveRecord::DestroyAssociationAsyncJob always
    destroyed records in the background.

    Nick Holden

  • Fix change_column_comment to preserve column's AUTO_INCREMENT in the MySQL adapter

    fatkodima

  • Fix quoting of ActiveSupport::Duration and Rational numbers in the MySQL adapter.

    Kevin McPhillips

  • Allow column name with COLLATE (e.g., title COLLATE "C") as safe SQL string

    Shugo Maeda

  • Permit underscores in the VERSION argument to database rake tasks.

    Eddie Lebow

  • Reversed the order of INSERT statements in structure.sql dumps

    This should decrease the likelihood of merge conflicts. New migrations
    will now be added at the top of the list.

    For existing apps, there will be a large diff the next time structure.sql
    is generated.

    Alex Ghiculescu, Matt Larraz

  • Fix PG.connect keyword arguments deprecation warning on ruby 2.7

    Fixes #44307.

    Nikita Vasilevsky

  • Fix dropping DB connections after serialization failures and deadlocks.

    Prior to 6.1.4, serialization failures and deadlocks caused rollbacks to be
    issued for both real transactions and savepoints. This breaks MySQL which
    disallows rollbacks of savepoints following a deadlock.

    6.1.4 removed these rollbacks, for both transactions and savepoints, causing
    the DB connection to be left in an unknown state and thus discarded.

    These rollbacks are now restored, except for savepoints on MySQL.

    Thomas Morgan

  • Make ActiveRecord::ConnectionPool Fiber-safe

    When ActiveSupport::IsolatedExecutionState.isolation_level is set to :fiber,
    the connection pool now supports multiple Fibers from the same Thread checking
    out connections from the pool.

    Alex Matchneer

  • Add update_attribute! to ActiveRecord::Persistence

    Similar to update_attribute, but raises ActiveRecord::RecordNotSaved when a before_* callback throws :abort.

    class Topic < ActiveRecord::Base
      before_save :check_title
    
      def check_title
        throw(:abort) if title == "abort"
      end
    end
    
    topic = Topic.create(title: "Test Title")
    # #=> #<Topic title: "Test Title">
    topic.update_attribute!(:title, "Another Title")
    # #=> #<Topic title: "Another Title">
    topic.update_attribute!(:title, "abort")
    # raises ActiveRecord::RecordNotSaved
    

    Drew Tempelmeyer

  • Avoid loading every record in ActiveRecord::Relation#pretty_print

    # Before
    pp Foo.all # Loads the whole table.
    
    # After
    pp Foo.all # Shows 10 items and an ellipsis.
    

    Ulysse Buonomo

  • Change QueryMethods#in_order_of to drop records not listed in values.

    in_order_of now filters down to the values provided, to match the behavior of the Enumerable version.

    Kevin Newton

  • Allow named expression indexes to be revertible.

    Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.

    add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
    

    Fixes #43331.

    Oliver Günther

  • Fix incorrect argument in PostgreSQL structure dump tasks.

    Updating the --no-comment argument added in Rails 7 to the correct --no-comments argument.

    Alex Dent

  • Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.

    Reference/belongs_to in migrations with version 6.0 were creating columns as
    bigint instead of integer for the SQLite Adapter.

    Marcelo Lauxen

  • Fix QueryMethods#in_order_of to handle empty order list.

    Post.in_order_of(:id, []).to_a
    

    Also more explicitly set the column as secondary order, so that any other
    value is still ordered.

    Jean Boussier

  • Fix quoting of column aliases generated by calculation methods.

    Since the alias is derived from the table name, we can't assume the result
    is a valid identifier.

    class Test < ActiveRecord::Base
      self.table_name = '1abc'
    end
    Test.group(:id).count
    # syntax error at or near "1" (ActiveRecord::StatementInvalid)
    # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
    

    Jean Boussier

  • Add authenticate_by when using has_secure_password.

    authenticate_by is intended to replace code like the following, which
    returns early when a user with a matching email is not found:

    User.find_by(email: "...")&.authenticate("...")
    

    Such code is vulnerable to timing-based enumeration attacks, wherein an
    attacker can determine if a user account with a given email exists. After
    confirming that an account exists, the attacker can try passwords associated
    with that email address from other leaked databases, in case the user
    re-used a password across multiple sites (a common practice). Additionally,
    knowing an account email address allows the attacker to attempt a targeted
    phishing ("spear phishing") attack.

    authenticate_by addresses the vulnerability by taking the same amount of
    time regardless of whether a user with a matching email is found:

    User.authenticate_by(email: "...", password: "...")
    

    Jonathan Hefner

Action View

  • Introduce ActionView::TestCase.register_parser

    register_parser :rss, -> rendered { RSS::Parser.parse(rendered) }
    
    test "renders RSS" do
      article = Article.create!(title: "Hello, world")
    
      render formats: :rss, partial: article
    
      assert_equal "Hello, world", rendered.rss.items.last.title
    end
    

    By default, register parsers for :html and :json.

    Sean Doyle

  • Fix simple_format with blank wrapper_tag option returns plain html tag

    By default simple_format method returns the text wrapped with <p>. But if we explicitly specify
    the wrapper_tag: nil in the options, it returns the text wrapped with <></> tag.

    Before:

    simple_format("Hello World", {},  { wrapper_tag: nil })
    # <>Hello World</>
    

    After:

    simple_format("Hello World", {},  { wrapper_tag: nil })
    # <p>Hello World</p>
    `

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.1.0.rc2

Active Support

  • Fix AS::MessagePack with ENV["RAILS_MAX_THREADS"].

    Jonathan Hefner

Active Model

  • No changes.

Active Record

  • Remove -shm and -wal SQLite files when rails db:drop is run.

    Niklas Häusele

  • Revert the change to raise an ArgumentError when #accepts_nested_attributes_for is declared more than once for
    an association in the same class.

    The reverted behavior broke the case where the #accepts_nested_attributes_for was defined in a concern and
    where overridden in the class that included the concern.

    Rafael Mendonça França

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • Make sure scheduled_at is a Time object when asserting enqueued jobs.

    Rafael Mendonça França

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Always set the Rails logger to be an instance of ActiveSupport::BroadcastLogger.

    Edouard Chin

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.1.0.rc1

Active Support

  • Add a new public API for broadcasting logs

    This feature existed for a while but was until now a private API.
    Broadcasting log allows to send log message to difference sinks (STDOUT, a file ...) and
    is used by default in the development environment to write logs both on STDOUT and in the
    "development.log" file.

    Basic usage:

    stdout_logger = Logger.new(STDOUT)
    file_logger = Logger.new("development.log")
    broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger, file_logger)
    
    broadcast.info("Hello!") # The "Hello!" message is written on STDOUT and in the log file.
    

    Adding other sink(s) to the broadcast:

    broadcast = ActiveSupport::BroadcastLogger.new
    broadcast.broadcast_to(Logger.new(STDERR))
    

    Remove a sink from the broadcast:

    stdout_logger = Logger.new(STDOUT)
    broadcast = ActiveSupport::BroadcastLogger.new(stdout_logger)
    
    broadcast.stop_broadcasting_to(stdout_logger)
    

    Edouard Chin

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

    Nobuyoshi Nakada, Shouichi Kamiya, Hartley McGuire

  • Use Ruby 3.3 Range#overlap? if available

    Yasuo Honda

Active Model

  • Remove change in the typography of user facing error messages.
    For example, “can’t be blank” is again “can't be blank”.

    Rafael Mendonça França

Active Record

  • Better naming for unique constraints support.

    Naming unique keys leads to misunderstanding it's a short-hand of unique indexes.
    Just naming it unique constraints is not misleading.

    In Rails 7.1.0.beta1 or before:

    add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_key :sections, name: "unique_section_position"
    

    Now:

    add_unique_constraint :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_constraint :sections, name: "unique_section_position"
    

    Ryuta Kamizono

  • 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

  • Performance tune the SQLite3 adapter connection configuration

    For Rails applications, the Write-Ahead-Log in normal syncing mode with a capped journal size, a healthy shared memory buffer and a shared cache will perform, on average, 2× better.

    Stephen Margheim

  • Allow SQLite3 busy_handler to be configured with simple max number of retries

    Retrying busy connections without delay is a preferred practice for performance-sensitive applications. Add support for a database.yml retries integer, which is used in a simple busy_handler function to retry busy connections without exponential backoff up to the max number of retries.

    Stephen Margheim

  • The SQLite3 adapter now supports supports_insert_returning?

    Implementing the full supports_insert_returning? contract means the SQLite3 adapter supports auto-populated columns (#48241) as well as custom primary keys.

    Stephen Margheim

  • Ensure the SQLite3 adapter handles default functions with the || concatenation operator

    Previously, this default function would produce the static string "'Ruby ' || 'on ' || 'Rails'".
    Now, the adapter will appropriately receive and use "Ruby on Rails".

    change_column_default "test_models", "ruby_on_rails", -> { "('Ruby ' || 'on ' || 'Rails')" }
    

    Stephen Margheim

  • Dump PostgreSQL schemas as part of the schema dump.

    Lachlan Sylvester

Action View

  • Introduce ActionView::TestCase.register_parser

    register_parser :rss, -> rendered { RSS::Parser.parse(rendered) }
    
    test "renders RSS" do
      article = Article.create!(title: "Hello, world")
    
      render formats: :rss, partial: article
    
      assert_equal "Hello, world", rendered.rss.items.last.title
    end
    

    By default, register parsers for :html and :json.

    Sean Doyle

Action Pack

  • Add support for #deep_merge and #deep_merge! to
    ActionController::Parameters.

    Sean Doyle

Active Job

  • Set scheduled_at attribute as a Time object instead of epoch seconds, and serialize and deserialize the value
    when enqueued. Assigning a numeric/epoch value to scheduled_at= is deprecated; use a Time object instead.

    Deserializes enqueued_at as a Time instead of ISO8601 String.

    Ben Sheldon

  • Clarify the backoff strategy for the recommended :wait option when retrying jobs

    wait: :exponentially_longer is waiting polynomially longer, so it is now recommended to use wait: :polynomially_longer to keep the same behavior.

    Victor Mours

Action Mailer

  • Introduce ActionMailer::FormBuilder

    Use the default_form_builder method in mailers to set the default form builder
    for templates rendered by that mailer. Matches the behaviour in Action Controller.

    Alex Ghiculescu

Action Cable

  • No changes.

Active Storage

  • Add expires_at option to ActiveStorage::Blob#signed_id.

    rails_blob_path(user.avatar, disposition: "attachment", expires_at: 30.minutes.from_now)
    <%= image_tag rails_blob_path(user.avatar.variant(resize: "100x100"), expires_at: 30.minutes.from_now) %>
    

    Aki

  • Allow attaching File and Pathname when assigning attributes, e.g.

    User.create!(avatar: File.open("image.jpg"))
    User.create!(avatar: file_fixture("image.jpg"))
    

    Dorian Marié

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Require concurrent-ruby in config/puma.rb so that Puma can boot in
    production when WEB_CONCURRENCY is not explicitly specified.

    Fixes #49323.

    Matt Brictson

  • Raise error when generating attribute with dangerous name.

    The following will now raise an error as save and hash are already
    defined by Active Record.

    $ bin/rails generate model Post save
    $ bin/rails generate model Post hash
    

    Petrik de Heus

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.1.0.beta1

Active Support

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

    Yasuo Honda

  • When using cache format version >= 7.1 or a custom serializer, expired and
    version-mismatched cache entries can now be detected without deserializing
    their values.

    Jonathan Hefner

  • Make all cache stores return a boolean for #delete

    Previously the RedisCacheStore#delete would return 1 if the entry
    exists and 0 otherwise. Now it returns true if the entry exists and false
    otherwise, just like the other stores.

    The FileStore would return nil if the entry doesn't exists and returns
    false now as well.

    Petrik de Heus

  • Active Support cache stores now support replacing the default compressor via
    a :compressor option. The specified compressor must respond to deflate
    and inflate. For example:

    module MyCompressor
      def self.deflate(string)
        # compression logic...
      end
    
      def self.inflate(compressed)
        # decompression logic...
      end
    end
    
    config.cache_store = :redis_cache_store, { compressor: MyCompressor }
    

    Jonathan Hefner

  • Active Support cache stores now support a :serializer option. Similar to
    the :coder option, serializers must respond to dump and load. However,
    serializers are only responsible for serializing a cached value, whereas
    coders are responsible for serializing the entire ActiveSupport::Cache::Entry
    instance. Additionally, the output from serializers can be automatically
    compressed, whereas coders are responsible for their own compression.

    Specifying a serializer instead of a coder also enables performance
    optimizations, including the bare string optimization introduced by cache
    format version 7.1.

    The :serializer and :coder options are mutually exclusive. Specifying
    both will raise an ArgumentError.

    Jonathan Hefner

  • Fix ActiveSupport::Inflector.humanize(nil) raising NoMethodError: undefined method `end_with?' for nil:NilClass.

    James Robinson

  • Don't show secrets for ActiveSupport::KeyGenerator#inspect.

    Before:

    ActiveSupport::KeyGenerator.new(secret).inspect
    "#<ActiveSupport::KeyGenerator:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveSupport::KeyGenerator::Aes256Gcm(secret).inspect
    "#<ActiveSupport::KeyGenerator:0x0000000104888038>"
    

    Petrik de Heus

  • Improve error message when EventedFileUpdateChecker is used without a
    compatible version of the Listen gem

    Hartley McGuire

  • Add :report behavior for Deprecation

    Setting config.active_support.deprecation = :report uses the error
    reporter to report deprecation warnings to ActiveSupport::ErrorReporter.

    Deprecations are reported as handled errors, with a severity of :warning.

    Useful to report deprecations happening in production to your bug tracker.

    Étienne Barrié

  • Rename Range#overlaps? to #overlap? and add alias for backwards compatibility

    Christian Schmidt

  • Fix EncryptedConfiguration returning incorrect values for some Hash
    methods

    Hartley McGuire

  • Don't show secrets for MessageEncryptor#inspect.

    Before:

    ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
    "#<ActiveSupport::MessageEncryptor:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm").inspect
    "#<ActiveSupport::MessageEncryptor:0x0000000104888038>"
    

    Petrik de Heus

  • Don't show contents for EncryptedConfiguration#inspect.

    Before:

    Rails.application.credentials.inspect
    "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8 ... @config={:secret=>\"something secret\"} ... @key_file_contents=\"915e4ea054e011022398dc242\" ...>"
    

    After:

    Rails.application.credentials.inspect
    "#<ActiveSupport::EncryptedConfiguration:0x000000010d2b38e8>"
    

    Petrik de Heus

  • ERB::Util.html_escape_once always returns an html_safe string.

    This method previously maintained the html_safe? property of a string on the return
    value. Because this string has been escaped, however, not marking it as html_safe causes
    entities to be double-escaped.

    As an example, take this view snippet:

    <p><%= html_escape_once("this & that &amp; the other") %></p>
    

    Before this change, that would be double-escaped and render as:

    <p>this &amp;amp; that &amp;amp; the other</p>
    

    After this change, it renders correctly as:

    <p>this &amp; that &amp; the other</p>
    

    Fixes #48256

    Mike Dalessio

  • Deprecate SafeBuffer#clone_empty.

    This method has not been used internally since Rails 4.2.0.

    Mike Dalessio

  • MessageEncryptor, MessageVerifier, and config.active_support.message_serializer
    now accept :message_pack and :message_pack_allow_marshal as serializers.
    These serializers require the msgpack gem
    (>= 1.7.0).

    The Message Pack format can provide improved performance and smaller payload
    sizes. It also supports round-tripping some Ruby types that are not supported
    by JSON. For example:

    verifier = ActiveSupport::MessageVerifier.new("secret")
    data = [{ a: 1 }, { b: 2 }.with_indifferent_access, 1.to_d, Time.at(0, 123)]
    message = verifier.generate(data)
    
    # BEFORE with config.active_support.message_serializer = :json
    verifier.verified(message)
    # => [{"a"=>1}, {"b"=>2}, "1.0", "1969-12-31T18:00:00.000-06:00"]
    verifier.verified(message).map(&:class)
    # => [Hash, Hash, String, String]
    
    # AFTER with config.active_support.message_serializer = :message_pack
    verifier.verified(message)
    # => [{:a=>1}, {"b"=>2}, 0.1e1, 1969-12-31 18:00:00.000123 -0600]
    verifier.verified(message).map(&:class)
    # => [Hash, ActiveSupport::HashWithIndifferentAccess, BigDecimal, Time]
    

    The :message_pack serializer can fall back to deserializing with
    ActiveSupport::JSON when necessary, and the :message_pack_allow_marshal
    serializer can fall back to deserializing with Marshal as well as
    ActiveSupport::JSON. Additionally, the :marshal, :json, and
    :json_allow_marshal serializers can now fall back to deserializing with
    ActiveSupport::MessagePack when necessary. These behaviors ensure old
    messages can still be read so that migration is easier.

    Jonathan Hefner

  • A new 7.1 cache format is available which includes an optimization for
    bare string values such as view fragments.

    The 7.1 cache format is used by default for new apps, and existing apps
    can enable the format by setting config.load_defaults 7.1 or by setting
    config.active_support.cache_format_version = 7.1 in config/application.rb
    or a config/environments/*.rb file.

    Cache entries written using the 6.1 or 7.0 cache formats can be read
    when using the 7.1 format. To perform a rolling deploy of a Rails 7.1
    upgrade, wherein servers that have not yet been upgraded must be able to
    read caches from upgraded servers, leave the cache format unchanged on the
    first deploy, then enable the 7.1 cache format on a subsequent deploy.

    Jonathan Hefner

  • Active Support cache stores can now use a preconfigured serializer based on
    ActiveSupport::MessagePack via the :serializer option:

    config.cache_store = :redis_cache_store, { serializer: :message_pack }
    

    The :message_pack serializer can reduce cache entry sizes and improve
    performance, but requires the msgpack gem
    (>= 1.7.0).

    The :message_pack serializer can read cache entries written by the default
    serializer, and the default serializer can now read entries written by the
    :message_pack serializer. These behaviors make it easy to migrate between
    serializer without invalidating the entire cache.

    Jonathan Hefner

  • Object#deep_dup no longer duplicate named classes and modules.

    Before:

    hash = { class: Object, module: Kernel }
    hash.deep_dup # => {:class=>#<Class:0x00000001063ffc80>, :module=>#<Module:0x00000001063ffa00>}
    

    After:

    hash = { class: Object, module: Kernel }
    hash.deep_dup # => {:class=>Object, :module=>Kernel}
    

    Jean Boussier

  • Consistently raise an ArgumentError if the ActiveSupport::Cache key is blank.

    Joshua Young

  • Deprecate usage of the singleton ActiveSupport::Deprecation.

    All usage of ActiveSupport::Deprecation as a singleton is deprecated, the most common one being
    ActiveSupport::Deprecation.warn. Gem authors should now create their own deprecator (ActiveSupport::Deprecation
    object), and use it to emit deprecation warnings.

    Calling any of the following without specifying a deprecator argument is also deprecated:

    • Module.deprecate
    • deprecate_constant
    • DeprecatedObjectProxy
    • DeprecatedInstanceVariableProxy
    • DeprecatedConstantProxy
    • deprecation-related test assertions

    Use of ActiveSupport::Deprecation.silence and configuration methods like behavior=, disallowed_behavior=,
    disallowed_warnings= should now be aimed at the application's deprecators.

    Rails.application.deprecators.silence do
      # code that emits deprecation warnings
    end
    

    If your gem has a Railtie or Engine, it's encouraged to add your deprecator to the application's deprecators, that
    way the deprecation related configuration options will apply to it as well, e.g.
    config.active_support.report_deprecations set to false in the production environment will also disable your
    deprecator.

    initializer "my_gem.deprecator" do |app|
      app.deprecators[:my_gem] = MyGem.deprecator
    end
    

    Étienne Barrié

  • Add Object#with to set and restore public attributes around a block

    client.timeout # => 5
    client.with(timeout: 1) do
      client.timeout # => 1
    end
    client.timeout # => 5
    

    Jean Boussier

  • Remove deprecated support to generate incorrect RFC 4122 UUIDs when providing a namespace ID that is not one of the
    constants defined on Digest::UUID.

    Rafael Mendonça França

  • Deprecate config.active_support.use_rfc4122_namespaced_uuids.

    Rafael Mendonça França

  • Remove implicit conversion of objects into String by ActiveSupport::SafeBuffer.

    Rafael Mendonça França

  • Remove deprecated active_support/core_ext/range/include_time_with_zone file.

    Rafael Mendonça França

  • Deprecate config.active_support.remove_deprecated_time_with_zone_name.

    Rafael Mendonça França

  • Remove deprecated override of ActiveSupport::TimeWithZone.name.

    Rafael Mendonça França

  • Deprecate config.active_support.disable_to_s_conversion.

    Rafael Mendonça França

  • Remove deprecated option to passing a format to #to_s in Array, Range, Date, DateTime, Time,
    BigDecimal, Float and, Integer.

    Rafael Mendonça França

  • Remove deprecated ActiveSupport::PerThreadRegistry.

    Rafael Mendonça França

  • Remove deprecated override of Enumerable#sum.

    Rafael Mendonça França

  • Deprecated initializing a ActiveSupport::Cache::MemCacheStore with an instance of Dalli::Client.

    Deprecate the undocumented option of providing an already-initialized instance of Dalli::Client to ActiveSupport::Cache::MemCacheStore. Such clients could be configured with unrecognized options, which could lead to unexpected behavior. Instead, provide addresses as documented.

    aledustet

  • Stub Time.new() in TimeHelpers#travel_to

    travel_to Time.new(2004, 11, 24) do
      # Inside the `travel_to` block `Time.new` is stubbed
      assert_equal Time.new.year, 2004
    end
    

    fatkodima

  • Raise ActiveSupport::MessageEncryptor::InvalidMessage from
    ActiveSupport::MessageEncryptor#decrypt_and_verify regardless of cipher.
    Previously, when a MessageEncryptor was using a non-AEAD cipher such as
    AES-256-CBC, a corrupt or tampered message would raise
    ActiveSupport::MessageVerifier::InvalidSignature. Now, all ciphers raise
    the same error:

    encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-gcm")
    message = encryptor.encrypt_and_sign("message")
    encryptor.decrypt_and_verify(message.next)
    # => raises ActiveSupport::MessageEncryptor::InvalidMessage
    
    encryptor = ActiveSupport::MessageEncryptor.new("x" * 32, cipher: "aes-256-cbc")
    message = encryptor.encrypt_and_sign("message")
    encryptor.decrypt_and_verify(message.next)
    # BEFORE:
    # => raises ActiveSupport::MessageVerifier::InvalidSignature
    # AFTER:
    # => raises ActiveSupport::MessageEncryptor::InvalidMessage
    

    Jonathan Hefner

  • Support nil original values when using ActiveSupport::MessageVerifier#verify.
    Previously, MessageVerifier#verify did not work with nil original
    values, though both MessageVerifier#verified and
    MessageEncryptor#decrypt_and_verify do:

    encryptor = ActiveSupport::MessageEncryptor.new(secret)
    message = encryptor.encrypt_and_sign(nil)
    
    encryptor.decrypt_and_verify(message)
    # => nil
    
    verifier = ActiveSupport::MessageVerifier.new(secret)
    message = verifier.generate(nil)
    
    verifier.verified(message)
    # => nil
    
    verifier.verify(message)
    # BEFORE:
    # => raises ActiveSupport::MessageVerifier::InvalidSignature
    # AFTER:
    # => nil
    

    Jonathan Hefner

  • Maintain html_safe? on html_safe strings when sliced with slice, slice!, or chr method.

    Previously, html_safe? was only maintained when the html_safe strings were sliced
    with [] method. Now, slice, slice!, and chr methods will maintain html_safe? like [] method.

    string = "<div>test</div>".html_safe
    string.slice(0, 1).html_safe? # => true
    string.slice!(0, 1).html_safe? # => true
    # maintain html_safe? after the slice!
    string.html_safe? # => true
    string.chr # => true
    

    Michael Go

  • Add Object#in? support for open ranges.

    assert Date.today.in?(..Date.tomorrow)
    assert_not Date.today.in?(Date.tomorrow..)
    

    Ignacio Galindo

  • config.i18n.raise_on_missing_translations = true now raises on any missing translation.

    Previously it would only raise when called in a view or controller. Now it will raise
    anytime I18n.t is provided an unrecognised key.

    If you do not want this behaviour, you can customise the i18n exception handler. See the
    upgrading guide or i18n guide for more information.

    Alex Ghiculescu

  • ActiveSupport::CurrentAttributes now raises if a restricted attribute name is used.

    Attributes such as set and reset cannot be used as they clash with the
    CurrentAttributes public API.

    Alex Ghiculescu

  • HashWithIndifferentAccess#transform_keys now takes a Hash argument, just
    as Ruby's Hash#transform_keys does.

    Akira Matsuda

  • delegate now defines method with proper arity when delegating to a Class.
    With this change, it defines faster method (3.5x faster with no argument).
    However, in order to gain this benefit, the delegation target method has to
    be defined before declaring the delegation.

    # This defines 3.5 times faster method than before
    class C
      def self.x() end
      delegate :x, to: :class
    end
    
    class C
      # This works but silently falls back to old behavior because
      # `delegate` cannot find the definition of `x`
      delegate :x, to: :class
      def self.x() end
    end
    

    Akira Matsuda

  • assert_difference message now includes what changed.

    This makes it easier to debug non-obvious failures.

    Before:

    "User.count" didn't change by 32.
    Expected: 1611
      Actual: 1579
    

    After:

    "User.count" didn't change by 32, but by 0.
    Expected: 1611
      Actual: 1579
    

    Alex Ghiculescu

  • Add ability to match exception messages to assert_raises assertion

    Instead of this

    error = assert_raises(ArgumentError) do
      perform_service(param: 'exception')
    end
    assert_match(/incorrect param/i, error.message)
    

    you can now write this

    assert_raises(ArgumentError, match: /incorrect param/i) do
      perform_service(param: 'exception')
    end
    

    fatkodima

  • Add Rails.env.local? shorthand for Rails.env.development? || Rails.env.test?.

    DHH

  • ActiveSupport::Testing::TimeHelpers now accepts named with_usec argument
    to freeze_time, travel, and travel_to methods. Passing true prevents
    truncating the destination time with change(usec: 0).

    KevSlashNull, and serprex

  • ActiveSupport::CurrentAttributes.resets now accepts a method name

    The block API is still the recommended approach, but now both APIs are supported:

    class Current < ActiveSupport::CurrentAttributes
      resets { Time.zone = nil }
      resets :clear_time_zone
    end
    

    Alex Ghiculescu

  • Ensure ActiveSupport::Testing::Isolation::Forking closes pipes

    Previously, Forking.run_in_isolation opened two ends of a pipe. The fork
    process closed the read end, wrote to it, and then terminated (which
    presumably closed the file descriptors on its end). The parent process
    closed the write end, read from it, and returned, never closing the read
    end.

    This resulted in an accumulation of open file descriptors, which could
    cause errors if the limit is reached.

    Sam Bostock

  • Fix Time#change and Time#advance for times around the end of Daylight
    Saving Time.

    Previously, when Time#change or Time#advance constructed a time inside
    the final stretch of Daylight Saving Time (DST), the non-DST offset would
    always be chosen for local times:

    # DST ended just before 2021-11-07 2:00:00 AM in US/Eastern.
    ENV["TZ"] = "US/Eastern"
    
    time = Time.local(2021, 11, 07, 00, 59, 59) + 1
    # => 2021-11-07 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0500
    
    time = Time.local(2021, 11, 06, 01, 00, 00)
    # => 2021-11-06 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(days: 1)
    # => 2021-11-07 01:00:00 -0500
    

    And the DST offset would always be chosen for times with a TimeZone
    object:

    Time.zone = "US/Eastern"
    
    time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
    # => 2021-11-07 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0400
    
    time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
    # => 2021-11-08 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(days: -1)
    # => 2021-11-07 01:00:00 -0400
    

    Now, Time#change and Time#advance will choose the offset that matches
    the original time's offset when possible:

    ENV["TZ"] = "US/Eastern"
    
    time = Time.local(2021, 11, 07, 00, 59, 59) + 1
    # => 2021-11-07 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0400
    
    time = Time.local(2021, 11, 06, 01, 00, 00)
    # => 2021-11-06 01:00:00 -0400
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0400
    time.advance(days: 1)
    # => 2021-11-07 01:00:00 -0400
    
    Time.zone = "US/Eastern"
    
    time = Time.new(2021, 11, 07, 02, 00, 00, Time.zone) - 3600
    # => 2021-11-07 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(seconds: 0)
    # => 2021-11-07 01:00:00 -0500
    
    time = Time.new(2021, 11, 8, 01, 00, 00, Time.zone)
    # => 2021-11-08 01:00:00 -0500
    time.change(day: 07)
    # => 2021-11-07 01:00:00 -0500
    time.advance(days: -1)
    # => 2021-11-07 01:00:00 -0500
    

    Kevin Hall, Takayoshi Nishida, and Jonathan Hefner

  • Fix MemoryStore to preserve entries TTL when incrementing or decrementing

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

    Jean Boussier

  • Rails.error.handle and Rails.error.record filter now by multiple error classes.

    Rails.error.handle(IOError, ArgumentError) do
      1 + '1' # raises TypeError
    end
    1 + 1 # TypeErrors are not IOErrors or ArgumentError, so this will *not* be handled
    

    Martin Spickermann

  • Class#subclasses and Class#descendants now automatically filter reloaded classes.

    Previously they could return old implementations of reloadable classes that have been
    dereferenced but not yet garbage collected.

    They now automatically filter such classes like DescendantTracker#subclasses and
    DescendantTracker#descendants.

    Jean Boussier

  • Rails.error.report now marks errors as reported to avoid reporting them twice.

    In some cases, users might want to report errors explicitly with some extra context
    before letting it bubble up.

    This also allows to safely catch and report errors outside of the execution context.

    Jean Boussier

  • Add assert_error_reported and assert_no_error_reported

    Allows to easily asserts an error happened but was handled

    report = assert_error_reported(IOError) do
      # ...
    end
    assert_equal "Oops", report.error.message
    assert_equal "admin", report.context[:section]
    assert_equal :warning, report.severity
    assert_predicate report, :handled?
    

    Jean Boussier

  • ActiveSupport::Deprecation behavior callbacks can now receive the
    deprecator instance as an argument. This makes it easier for such callbacks
    to change their behavior based on the deprecator's state. For example,
    based on the deprecator's debug flag.

    3-arity and splat-args callbacks such as the following will now be passed
    the deprecator instance as their third argument:

    • ->(message, callstack, deprecator) { ... }
    • ->(*args) { ... }
    • ->(message, *other_args) { ... }

    2-arity and 4-arity callbacks such as the following will continue to behave
    the same as before:

    • ->(message, callstack) { ... }
    • ->(message, callstack, deprecation_horizon, gem_name) { ... }
    • ->(message, callstack, *deprecation_details) { ... }

    Jonathan Hefner

  • ActiveSupport::Deprecation#disallowed_warnings now affects the instance on
    which it is configured.

    This means that individual ActiveSupport::Deprecation instances can be
    configured with their own disallowed warnings, and the global
    ActiveSupport::Deprecation.disallowed_warnings now only affects the global
    ActiveSupport::Deprecation.warn.

    Before

    ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
    deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
    deprecator.disallowed_warnings = ["bar"]
    
    ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
    ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
    deprecator.warn("foo")                 # => raise ActiveSupport::DeprecationException
    deprecator.warn("bar")                 # => print "DEPRECATION WARNING: bar"
    

    After

    ActiveSupport::Deprecation.disallowed_warnings = ["foo"]
    deprecator = ActiveSupport::Deprecation.new("2.0", "MyCoolGem")
    deprecator.disallowed_warnings = ["bar"]
    
    ActiveSupport::Deprecation.warn("foo") # => raise ActiveSupport::DeprecationException
    ActiveSupport::Deprecation.warn("bar") # => print "DEPRECATION WARNING: bar"
    deprecator.warn("foo")                 # => print "DEPRECATION WARNING: foo"
    deprecator.warn("bar")                 # => raise ActiveSupport::DeprecationException
    

    Note that global ActiveSupport::Deprecation methods such as ActiveSupport::Deprecation.warn
    and ActiveSupport::Deprecation.disallowed_warnings have been deprecated.

    Jonathan Hefner

  • Add italic and underline support to ActiveSupport::LogSubscriber#color

    Previously, only bold text was supported via a positional argument.
    This allows for bold, italic, and underline options to be specified
    for colored logs.

    info color("Hello world!", :red, bold: true, underline: true)
    

    Gannon McGibbon

  • Add String#downcase_first method.

    This method is the corollary of String#upcase_first.

    Mark Schneider

  • thread_mattr_accessor will call .dup.freeze on non-frozen default values.

    This provides a basic level of protection against different threads trying
    to mutate a shared default object.

    Jonathan Hefner

  • Add raise_on_invalid_cache_expiration_time config to ActiveSupport::Cache::Store

    Specifies if an ArgumentError should be raised if Rails.cache fetch or
    write are given an invalid expires_at or expires_in time.

    Options are true, and false. If false, the exception will be reported
    as handled and logged instead. Defaults to true if config.load_defaults >= 7.1.

    Trevor Turk

  • ActiveSupport::Cache:Store#fetch now passes an options accessor to the block.

    It makes possible to override cache options:

    Rails.cache.fetch("3rd-party-token") do |name, options|
      token = fetch_token_from_remote
      # set cache's TTL to match token's TTL
      options.expires_in = token.expires_in
      token
    end
    

    Andrii Gladkyi, Jean Boussier

  • default option of thread_mattr_accessor now applies through inheritance and
    also across new threads.

    Previously, the default value provided was set only at the moment of defining
    the attribute writer, which would cause the attribute to be uninitialized in
    descendants and in other threads.

    Fixes #43312.

    Thierry Deo

  • Redis cache store is now compatible with redis-rb 5.0.

    Jean Boussier

  • Add skip_nil: support to ActiveSupport::Cache::Store#fetch_multi.

    Daniel Alfaro

  • Add quarter method to date/time

    Matt Swanson

  • Fix NoMethodError on custom ActiveSupport::Deprecation behavior.

    ActiveSupport::Deprecation.behavior= was supposed to accept any object
    that responds to call, but in fact its internal implementation assumed that
    this object could respond to arity, so it was restricted to only Proc objects.

    This change removes this arity restriction of custom behaviors.

    Ryo Nakamura

  • Support :url_safe option for MessageEncryptor.

    The MessageEncryptor constructor now accepts a :url_safe option, similar
    to the MessageVerifier constructor. When enabled, this option ensures
    that messages use a URL-safe encoding.

    Jonathan Hefner

  • Add url_safe option to ActiveSupport::MessageVerifier initializer

    ActiveSupport::MessageVerifier.new now takes optional url_safe argument.
    It can generate URL-safe strings by passing url_safe: true.

    verifier = ActiveSupport::MessageVerifier.new(url_safe: true)
    message = verifier.generate(data) # => URL-safe string
    

    This option is false by default to be backwards compatible.

    Shouichi Kamiya

  • Enable connection pooling by default for MemCacheStore and RedisCacheStore.

    If you want to disable connection pooling, set :pool option to false when configuring the cache store:

    config.cache_store = :mem_cache_store, "cache.example.com", pool: false
    

    fatkodima

  • Add force: support to ActiveSupport::Cache::Store#fetch_multi.

    fatkodima

  • Deprecated :pool_size and :pool_timeout options for configuring connection pooling in cache stores.

    Use pool: true to enable pooling with default settings:

    config.cache_store = :redis_cache_store, pool: true
    

    Or pass individual options via :pool option:

    config.cache_store = :redis_cache_store, pool: { size: 10, timeout: 2 }
    

    fatkodima

  • Allow #increment and #decrement methods of ActiveSupport::Cache::Store
    subclasses to set new values.

    Previously incrementing or decrementing an unset key would fail and return
    nil. A default will now be assumed and the key will be created.

    Andrej Blagojević, Eugene Kenny

  • Add skip_nil: support to RedisCacheStore

    Joey Paris

  • ActiveSupport::Cache::MemoryStore#write(name, val, unless_exist:true) now
    correctly writes expired keys.

    Alan Savage

  • ActiveSupport::ErrorReporter now accepts and forward a source: parameter.

    This allow libraries to signal the origin of the errors, and reporters
    to easily ignore some sources.

    Jean Boussier

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

  • Respect ActiveSupport::Logger.new's :formatter keyword argument

    The stdlib Logger::new allows passing a :formatter keyword argument to
    set the logger's formatter. Previously ActiveSupport::Logger.new ignored
    that argument by always setting the formatter to an instance of
    ActiveSupport::Logger::SimpleFormatter.

    Steven Harman

  • Deprecate preserving the pre-Ruby 2.4 behavior of to_time

    With Ruby 2.4+ the default for +to_time+ changed from converting to the
    local system time to preserving the offset of the receiver. At the time Rails
    supported older versions of Ruby so a compatibility layer was added to assist
    in the migration process. From Rails 5.0 new applications have defaulted to
    the Ruby 2.4+ behavior and since Rails 7.0 now only supports Ruby 2.7+
    this compatibility layer can be safely removed.

    To minimize any noise generated the deprecation warning only appears when the
    setting is configured to false as that is the only scenario where the
    removal of the compatibility layer has any effect.

    Andrew White

  • Pathname.blank? only returns true for Pathname.new("")

    Previously it would end up calling Pathname#empty? which returned true
    if the path existed and was an empty directory or file.

    That behavior was unlikely to be expected.

    Jean Boussier

  • Deprecate Notification::Event's #children and #parent_of?

    John Hawthorn

  • Change the default serializer of ActiveSupport::MessageVerifier from
    Marshal to ActiveSupport::JSON when using config.load_defaults 7.1.

    Messages serialized with Marshal can still be read, but new messages will
    be serialized with ActiveSupport::JSON. For more information, see
    https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.

    Saba Kiaei, David Buckley, and Jonathan Hefner

  • Change the default serializer of ActiveSupport::MessageEncryptor from
    Marshal to ActiveSupport::JSON when using config.load_defaults 7.1.

    Messages serialized with Marshal can still be read, but new messages will
    be serialized with ActiveSupport::JSON. For more information, see
    https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer.

    Zack Deveau, Martin Gingras, and Jonathan Hefner

  • Add ActiveSupport::TestCase#stub_const to stub a constant for the duration of a yield.

    DHH

  • Fix ActiveSupport::EncryptedConfiguration to be compatible with Psych 4

    Stephen Sugden

  • Improve File.atomic_write error handling

    Daniel Pepper

  • Fix Class#descendants and DescendantsTracker#descendants compatibility with Ruby 3.1.

    The native Class#descendants was reverted prior to Ruby 3.1 release,
    but Class#subclasses was kept, breaking the feature detection.

    Jean Boussier

Active Model

  • Support composite identifiers in to_key

    to_key avoids wrapping #id value into an Array if #id already an array

    Nikita Vasilevsky

  • Add ActiveModel::Conversion.param_delimiter to configure delimiter being used in to_param

    Nikita Vasilevsky

  • undefine_attribute_methods undefines alias attribute methods along with attribute methods.

    Nikita Vasilevsky

  • Error.full_message now strips ":base" from the message.

    zzak

  • Add a load hook for ActiveModel::Model (named active_model) to match the load hook for
    ActiveRecord::Base and allow for overriding aspects of the ActiveModel::Model class.

    Lewis Buckley

  • Improve password length validation in ActiveModel::SecurePassword to consider byte size for BCrypt
    compatibility.

    The previous password length validation only considered the character count, which may not
    accurately reflect the 72-byte size limit imposed by BCrypt. This change updates the validation
    to consider both character count and byte size while keeping the character length validation in place.

    user = User.new(password: "a" * 73)  # 73 characters
    user.valid? # => false
    user.errors[:password] # => ["is too long"]
    
    
    user = User.new(password: "" * 25)  # 25 characters, 75 bytes
    user.valid? # => false
    user.errors[:password] # => ["is too long"]
    

    ChatGPT, Guillermo Iguaran

  • has_secure_password now generates an #{attribute}_salt method that returns the salt
    used to compute the password digest. The salt will change whenever the password is changed,
    so it can be used to create single-use password reset tokens with generates_token_for:

    class User < ActiveRecord::Base
      has_secure_password
    
      generates_token_for :password_reset, expires_in: 15.minutes do
        password_salt&.last(10)
      end
    end
    

    Lázaro Nixon

  • Improve typography of user facing error messages. In English contractions,
    the Unicode APOSTROPHE (U+0027) is now RIGHT SINGLE QUOTATION MARK
    (U+2019). For example, "can't be blank" is now "can’t be blank".

    Jon Dufresne

  • Add class to ActiveModel::MissingAttributeError error message.

    Show which class is missing the attribute in the error message:

    user = User.first
    user.pets.select(:id).first.user_id
    # => ActiveModel::MissingAttributeError: missing attribute 'user_id' for Pet
    

    Petrik de Heus

  • Raise NoMethodError in ActiveModel::Type::Value#as_json to avoid unpredictable
    results.

    Vasiliy Ermolovich

  • Custom attribute types that inherit from Active Model built-in types and do
    not override the serialize method will now benefit from an optimization
    when serializing attribute values for the database.

    For example, with a custom type like the following:

    class DowncasedString < ActiveModel::Type::String
      def cast(value)
        super&.downcase
      end
    end
    
    ActiveRecord::Type.register(:downcased_string, DowncasedString)
    
    class User < ActiveRecord::Base
      attribute :email, :downcased_string
    end
    
    user = User.new(email: "FooBar@example.com")
    

    Serializing the email attribute for the database will be roughly twice as
    fast. More expensive cast operations will likely see greater improvements.

    Jonathan Hefner

  • has_secure_password now supports password challenges via a
    password_challenge accessor and validation.

    A password challenge is a safeguard to verify that the current user is
    actually the password owner. It can be used when changing sensitive model
    fields, such as the password itself. It is different than a password
    confirmation, which is used to prevent password typos.

    When password_challenge is set, the validation checks that the value's
    digest matches the currently persisted password_digest (i.e.
    password_digest_was).

    This allows a password challenge to be done as part of a typical update
    call, just like a password confirmation. It also allows a password
    challenge error to be handled in the same way as other validation errors.

    For example, in the controller, instead of:

    password_params = params.require(:password).permit(
      :password_challenge,
      :password,
      :password_confirmation,
    )
    
    password_challenge = password_params.delete(:password_challenge)
    @password_challenge_failed = !current_user.authenticate(password_challenge)
    
    if !@password_challenge_failed && current_user.update(password_params)
      # ...
    end
    

    You can now write:

    password_params = params.require(:password).permit(
      :password_challenge,
      :password,
      :password_confirmation,
    ).with_defaults(password_challenge: "")
    
    if current_user.update(password_params)
      # ...
    end
    

    And, in the view, instead of checking @password_challenge_failed, you can
    render an error for the password_challenge field just as you would for
    other form fields, including utilizing config.action_view.field_error_proc.

    Jonathan Hefner

  • Support infinite ranges for LengthValidators :in/:within options

    validates_length_of :first_name, in: ..30
    

    fatkodima

  • Add support for beginless ranges to inclusivity/exclusivity validators:

    validates_inclusion_of :birth_date, in: -> { (..Date.today) }
    

    Bo Jeanes

  • Make validators accept lambdas without record argument

    # Before
    validates_comparison_of :birth_date, less_than_or_equal_to: ->(_record) { Date.today }
    
    # After
    validates_comparison_of :birth_date, less_than_or_equal_to: -> { Date.today }
    

    fatkodima

  • Fix casting long strings to Date, Time or DateTime

    fatkodima

  • Use different cache namespace for proxy calls

    Models can currently have different attribute bodies for the same method
    names, leading to conflicts. Adding a new namespace :active_model_proxy
    fixes the issue.

    Chris Salzberg

Active Record

  • Encryption now supports support_unencrypted_data being set per-attribute.

    You can now opt out of support_unencrypted_data on a specific encrypted attribute.
    This only has an effect if ActiveRecord::Encryption.config.support_unencrypted_data == true.

    class User < ActiveRecord::Base
      encrypts :name, deterministic: true, support_unencrypted_data: false
      encrypts :email, deterministic: true
    end
    

    Alex Ghiculescu

  • Add instrumentation for Active Record transactions

    Allows subscribing to transaction events for tracking/instrumentation. The event payload contains the connection, as well as timing details.

    ActiveSupport::Notifications.subscribe("transaction.active_record") do |event|
      puts "Transaction event occurred!"
      connection = event.payload[:connection]
      puts "Connection: #{connection.inspect}"
    end
    

    Daniel Colson, Ian Candy

  • Support composite foreign keys via migration helpers.

    # Assuming "carts" table has "(shop_id, user_id)" as a primary key.
    
    add_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
    
    remove_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id])
    foreign_key_exists?(:orders, :carts, primary_key: [:shop_id, :user_id])
    

    fatkodima

  • Adds support for if_not_exists when adding a check constraint.

    add_check_constraint :posts, "post_type IN ('blog', 'comment', 'share')", if_not_exists: true
    

    Cody Cutrer

  • Raise an ArgumentError when #accepts_nested_attributes_for is declared more than once for an association in
    the same class. Previously, the last declaration would silently override the previous one. Overriding in a subclass
    is still allowed.

    Joshua Young

  • Deprecate rewhere argument on #merge.

    The rewhere argument on #mergeis deprecated without replacement and
    will be removed in Rails 7.2.

    Adam Hess

  • Fix unscope is not working in specific case

    Before:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
    
    

    After:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
    

    Fixes #48094.

    Kazuya Hatanaka

  • Change has_secure_token default to on: :initialize

    Change the new default value from on: :create to on: :initialize

    Can be controlled by the config.active_record.generate_secure_token_on
    configuration:

    config.active_record.generate_secure_token_on = :create
    

    Sean Doyle

  • Fix change_column not setting precision: 6 on datetime columns when
    using 7.0+ Migrations and SQLite.

    Hartley McGuire

  • Support composite identifiers in to_key

    to_key avoids wrapping #id value into an Array if #id already an array

    Nikita Vasilevsky

  • Add validation option for enum

    class Contract < ApplicationRecord
      enum :status, %w[in_progress completed], validate: true
    end
    Contract.new(status: "unknown").valid? # => false
    Contract.new(status: nil).valid? # => false
    Contract.new(status: "completed").valid? # => true
    
    class Contract < ApplicationRecord
      enum :status, %w[in_progress completed], validate: { allow_nil: true }
    end
    Contract.new(status: "unknown").valid? # => false
    Contract.new(status: nil).valid? # => true
    Contract.new(status: "completed").valid? # => true
    

    Edem Topuzov, Ryuta Kamizono

  • Allow batching methods to use already loaded relation if available

    Calling batch methods on already loaded relations will use the records previously loaded instead of retrieving
    them from the database again.

    Adam Hess

  • Deprecate read_attribute(:id) returning the primary key if the primary key is not :id.

    Starting in Rails 7.2, read_attribute(:id) will return the value of the id column, regardless of the model's
    primary key. To retrieve the value of the primary key, use #id instead. read_attribute(:id) for composite
    primary key models will now return the value of the id column.

    Adrianna Chang

  • Fix change_table setting datetime precision for 6.1 Migrations

    Hartley McGuire

  • Fix change_column setting datetime precision for 6.1 Migrations

    Hartley McGuire

  • Add ActiveRecord::Base#id_value alias to access the raw value of a record's id column.

    This alias is only provided for models that declare an :id column.

    Adrianna Chang

  • Fix previous change tracking for ActiveRecord::Store when using a column with JSON structured database type

    Before, the methods to access the changes made during the last save #saved_change_to_key?, #saved_change_to_key, and #key_before_last_save did not work if the store was defined as a store_accessor on a column with a JSON structured database type

    Robert DiMartino

  • Fully support NULLS [NOT] DISTINCT for PostgreSQL 15+ indexes.

    Previous work was done to allow the index to be created in a migration, but it was not
    supported in schema.rb. Additionally, the matching for NULLS [NOT] DISTINCT was not
    in the correct order, which could have resulted in inconsistent schema detection.

    Gregory Jones

  • Allow escaping of literal colon characters in sanitize_sql_* methods when named bind variables are used

    Justin Bull

  • Fix #previously_new_record? to return true for destroyed records.

    Before, if a record was created and then destroyed, #previously_new_record? would return true.
    Now, any UPDATE or DELETE to a record is considered a change, and will result in #previously_new_record?
    returning false.

    Adrianna Chang

  • Specify callback in has_secure_token

    class User < ApplicationRecord
      has_secure_token on: :initialize
    end
    
    User.new.token # => "abc123...."
    

    Sean Doyle

  • Fix incrementation of in memory counter caches when associations overlap

    When two associations had a similarly named counter cache column, Active Record
    could sometime increment the wrong one.

    Jacopo Beschi, Jean Boussier

  • Don't show secrets for Active Record's Cipher::Aes256Gcm#inspect.

    Before:

    ActiveRecord::Encryption::Cipher::Aes256Gcm.new(secret).inspect
    "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038 ... @secret=\"\\xAF\\bFh]LV}q\\nl\\xB2U\\xB3 ... >"
    

    After:

    ActiveRecord::Encryption::Cipher::Aes256Gcm(secret).inspect
    "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038>"
    

    Petrik de Heus

  • Bring back the historical behavior of committing transaction on non-local return.

    Model.transaction do
      model.save
      return
      other_model.save # not executed
    end
    

    Historically only raised errors would trigger a rollback, but in Ruby 2.3, the timeout library
    started using throw to interrupt execution which had the adverse effect of committing open transactions.

    To solve this, in Active Record 6.1 the behavior was changed to instead rollback the transaction as it was safer
    than to potentially commit an incomplete transaction.

    Using return, break or throw inside a transaction block was essentially deprecated from Rails 6.1 onwards.

    However with the release of timeout 0.4.0, Timeout.timeout now raises an error again, and Active Record is able
    to return to its original, less surprising, behavior.

    This historical behavior can now be opt-ed in via:

    Rails.application.config.active_record.commit_transaction_on_non_local_return = true
    

    And is the default for new applications created in Rails 7.1.

    Jean Boussier

  • Deprecate name argument on #remove_connection.

    The name argument is deprecated on #remove_connection without replacement. #remove_connection should be called directly on the class that established the connection.

    Eileen M. Uchitelle

  • Fix has_one through singular building with inverse.

    Allows building of records from an association with a has_one through a
    singular association with inverse. For belongs_to through associations,
    linking the foreign key to the primary key model isn't needed.
    For has_one, we cannot build records due to the association not being mutable.

    Gannon McGibbon

  • Disable database prepared statements when query logs are enabled

    Prepared Statements and Query Logs are incompatible features due to query logs making every query unique.

    zzak, Jean Boussier

  • Support decrypting data encrypted non-deterministically with a SHA1 hash digest.

    This adds a new Active Record encryption option to support decrypting data encrypted
    non-deterministically with a SHA1 hash digest:

    Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
    

    The new option addresses a problem when upgrading from 7.0 to 7.1. Due to a bug in how Active Record
    Encryption was getting initialized, the key provider used for non-deterministic encryption were using
    SHA-1 as its digest class, instead of the one configured globally by Rails via
    Rails.application.config.active_support.key_generator_hash_digest_class.

    Cadu Ribeiro and Jorge Manrubia

  • Added PostgreSQL migration commands for enum rename, add value, and rename value.

    rename_enum and rename_enum_value are reversible. Due to Postgres
    limitation, add_enum_value is not reversible since you cannot delete enum
    values. As an alternative you should drop and recreate the enum entirely.

    rename_enum :article_status, to: :article_state
    
    add_enum_value :article_state, "archived" # will be at the end of existing values
    add_enum_value :article_state, "in review", before: "published"
    add_enum_value :article_state, "approved", after: "in review"
    
    rename_enum_value :article_state, from: "archived", to: "deleted"
    

    Ray Faddis

  • Allow composite primary key to be derived from schema

    Booting an application with a schema that contains composite primary keys
    will not issue warning and won't nilify the ActiveRecord::Base#primary_key value anymore.

    Given a travel_routes table definition and a TravelRoute model like:

    create_table :travel_routes, primary_key: [:origin, :destination], force: true do |t|
      t.string :origin
      t.string :destination
    end
    
    class TravelRoute < ActiveRecord::Base; end
    

    The TravelRoute.primary_key value will be automatically derived to ["origin", "destination"]

    Nikita Vasilevsky

  • Include the connection_pool with exceptions raised from an adapter.

    The connection_pool provides added context such as the connection used
    that led to the exception as well as which role and shard.

    Luan Vieira

  • Support multiple column ordering for find_each, find_in_batches and in_batches.

    When find_each/find_in_batches/in_batches are performed on a table with composite primary keys, ascending or descending order can be selected for each key.

    Person.find_each(order: [:desc, :asc]) do |person|
      person.party_all_night!
    end
    

    Takuya Kurimoto

  • Fix where on association with has_one/has_many polymorphic relations.

    Before:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
    

    Later:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
    

    Lázaro Nixon

  • Assign auto populated columns on Active Record record creation.

    Changes record creation logic to allow for the auto_increment column to be assigned
    immediately after creation regardless of it's relation to the model's primary key.

    The PostgreSQL adapter benefits the most from the change allowing for any number of auto-populated
    columns to be assigned on the object immediately after row insertion utilizing the RETURNING statement.

    Nikita Vasilevsky

  • Use the first key in the shards hash from connected_to for the default_shard.

    Some applications may not want to use :default as a shard name in their connection model. Unfortunately Active Record expects there to be a :default shard because it must assume a shard to get the right connection from the pool manager. Rather than force applications to manually set this, connects_to can infer the default shard name from the hash of shards and will now assume that the first shard is your default.

    For example if your model looked like this:

    class ShardRecord < ApplicationRecord
      self.abstract_class = true
    
      connects_to shards: {
        shard_one: { writing: :shard_one },
        shard_two: { writing: :shard_two }
      }
    

    Then the default_shard for this class would be set to shard_one.

    Fixes: #45390

    Eileen M. Uchitelle

  • Fix mutation detection for serialized attributes backed by binary columns.

    Jean Boussier

  • Add ActiveRecord.disconnect_all! method to immediately close all connections from all pools.

    Jean Boussier

  • Discard connections which may have been left in a transaction.

    There are cases where, due to an error, within_new_transaction may unexpectedly leave a connection in an open transaction. In these cases the connection may be reused, and the following may occur:

    • Writes appear to fail when they actually succeed.
    • Writes appear to succeed when they actually fail.
    • Reads return stale or uncommitted data.

    Previously, the following case was detected:

    • An error is encountered during the transaction, then another error is encountered while attempting to roll it back.

    Now, the following additional cases are detected:

    • An error is encountered just after successfully beginning a transaction.
    • An error is encountered while committing a transaction, then another error is encountered while attempting to roll it back.
    • An error is encountered while rolling back a transaction.

    Nick Dower

  • Active Record query cache now evicts least recently used entries

    By default it only keeps the 100 most recently used queries.

    The cache size can be configured via database.yml

    development:
      adapter: mysql2
      query_cache: 200
    

    It can also be entirely disabled:

    development:
      adapter: mysql2
      query_cache: false
    

    Jean Boussier

  • Deprecate check_pending! in favor of check_all_pending!.

    check_pending! will only check for pending migrations on the current database connection or the one passed in. This has been deprecated in favor of check_all_pending! which will find all pending migrations for the database configurations in a given environment.

    Eileen M. Uchitelle

  • Make increment_counter/decrement_counter accept an amount argument

    Post.increment_counter(:comments_count, 5, by: 3)
    

    fatkodima

  • Add support for Array#intersect? to ActiveRecord::Relation.

    Array#intersect? is only available on Ruby 3.1 or later.

    This allows the Rubocop Style/ArrayIntersect cop to work with ActiveRecord::Relation objects.

    John Harry Kelly

  • The deferrable foreign key can be passed to t.references.

    Hiroyuki Ishii

  • Deprecate deferrable: true option of add_foreign_key.

    deferrable: true is deprecated in favor of deferrable: :immediate, and
    will be removed in Rails 7.2.

    Because deferrable: true and deferrable: :deferred are hard to understand.
    Both true and :deferred are truthy values.
    This behavior is the same as the deferrable option of the add_unique_key method, added in #46192.

    Hiroyuki Ishii

  • AbstractAdapter#execute and #exec_query now clear the query cache

    If you need to perform a read only SQL query without clearing the query
    cache, use AbstractAdapter#select_all.

    Jean Boussier

  • Make .joins / .left_outer_joins work with CTEs.

    For example:

    Post
     .with(commented_posts: Comment.select(:post_id).distinct)
     .joins(:commented_posts)
    #=> WITH (...) SELECT ... INNER JOIN commented_posts on posts.id = commented_posts.post_id
    

    Vladimir Dementyev

  • Add a load hook for ActiveRecord::ConnectionAdapters::Mysql2Adapter
    (named active_record_mysql2adapter) to allow for overriding aspects of the
    ActiveRecord::ConnectionAdapters::Mysql2Adapter class. This makes Mysql2Adapter
    consistent with PostgreSQLAdapter and SQLite3Adapter that already have load hooks.

    fatkodima

  • Introduce adapter for Trilogy database client

    Trilogy is a MySQL-compatible database client. Rails applications can use Trilogy
    by configuring their config/database.yml:

    development:
    adapter: trilogy
    database: blog_development
    pool: 5
    

    Or by using the DATABASE_URL environment variable:

    ENV['DATABASE_URL'] # => "trilogy://localhost/blog_development?pool=5"
    

    Adrianna Chang

  • after_commit callbacks defined on models now execute in the correct order.

    class User < ActiveRecord::Base
      after_commit { puts("this gets called first") }
      after_commit { puts("this gets called second") }
    end
    

    Previously, the callbacks executed in the reverse order. To opt in to the new behaviour:

    config.active_record.run_after_transaction_callbacks_in_order_defined = true
    

    This is the default for new apps.

    Alex Ghiculescu

  • Infer foreign_key when inverse_of is present on has_one and has_many associations.

    has_many :citations, foreign_key: "book1_id", inverse_of: :book
    

    can be simplified to

    has_many :citations, inverse_of: :book
    

    and the foreign_key will be read from the corresponding belongs_to association.

    Daniel Whitney

  • Limit max length of auto generated index names

    Auto generated index names are now limited to 62 bytes, which fits within
    the default index name length limits for MySQL, Postgres and SQLite.

    Any index name over the limit will fallback to the new short format.

    Before (too long):

    index_testings_on_foo_and_bar_and_first_name_and_last_name_and_administrator
    

    After (short format):

    idx_on_foo_bar_first_name_last_name_administrator_5939248142
    

    The short format includes a hash to ensure the name is unique database-wide.

    Mike Coutermarsh

  • Introduce a more stable and optimized Marshal serializer for Active Record models.

    Can be enabled with config.active_record.marshalling_format_version = 7.1.

    Jean Boussier

  • Allow specifying where clauses with column-tuple syntax.

    Querying through #where now accepts a new tuple-syntax which accepts, as
    a key, an array of columns and, as a value, an array of corresponding tuples.
    The key specifies a list of columns, while the value is an array of
    ordered-tuples that conform to the column list.

    For instance:

    # Cpk::Book => Cpk::Book(author_id: integer, number: integer, title: string, revision: integer)
    # Cpk::Book.primary_key => ["author_id", "number"]
    
    book = Cpk::Book.create!(author_id: 1, number: 1)
    Cpk::Book.where(Cpk::Book.primary_key => [[1, 2]]) # => [book]
    
    # Topic => Topic(id: integer, title: string, author_name: string...)
    
    Topic.where([:title, :author_name] => [["The Alchemist", "Paul Coelho"], ["Harry Potter", "J.K Rowling"]])
    

    Paarth Madan

  • Allow warning codes to be ignore when reporting SQL warnings.

    Active Record config that can ignore warning codes

    # Configure allowlist of warnings that should always be ignored
    config.active_record.db_warnings_ignore = [
      "1062", # MySQL Error 1062: Duplicate entry
    ]
    

    This is supported for the MySQL and PostgreSQL adapters.

    Nick Borromeo

  • Introduce :active_record_fixtures lazy load hook.

    Hooks defined with this name will be run whenever TestFixtures is included
    in a class.

    ActiveSupport.on_load(:active_record_fixtures) do
      self.fixture_paths << "test/fixtures"
    end
    
    klass = Class.new
    klass.include(ActiveRecord::TestFixtures)
    
    klass.fixture_paths # => ["test/fixtures"]
    

    Andrew Novoselac

  • Introduce TestFixtures#fixture_paths.

    Multiple fixture paths can now be specified using the #fixture_paths accessor.
    Apps will continue to have test/fixtures as their one fixture path by default,
    but additional fixture paths can be specified.

    ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
    ActiveSupport::TestCase.fixture_paths << "component2/test/fixtures"
    

    TestFixtures#fixture_path is now deprecated.

    Andrew Novoselac

  • Adds support for deferrable exclude constraints in PostgreSQL.

    By default, exclude constraints in PostgreSQL are checked after each statement.
    This works for most use cases, but becomes a major limitation when replacing
    records with overlapping ranges by using multiple statements.

    exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :immediate
    

    Passing deferrable: :immediate checks constraint after each statement,
    but allows manually deferring the check using SET CONSTRAINTS ALL DEFERRED
    within a transaction. This will cause the excludes to be checked after the transaction.

    It's also possible to change the default behavior from an immediate check
    (after the statement), to a deferred check (after the transaction):

    exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :deferred
    

    Hiroyuki Ishii

  • Respect foreign_type option to delegated_type for {role}_class method.

    Usage of delegated_type with non-conventional {role}_type column names can now be specified with foreign_type option.
    This option is the same as foreign_type as forwarded to the underlying belongs_to association that delegated_type wraps.

    Jason Karns

  • Add support for unique constraints (PostgreSQL-only).

    add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position"
    remove_unique_key :sections, name: "unique_section_position"
    

    See PostgreSQL's Unique Constraints documentation for more on unique constraints.

    By default, unique constraints in PostgreSQL are checked after each statement.
    This works for most use cases, but becomes a major limitation when replacing
    records with unique column by using multiple statements.

    An example of swapping unique columns between records.

    # position is unique column
    old_item = Item.create!(position: 1)
    new_item = Item.create!(position: 2)
    
    Item.transaction do
      old_item.update!(position: 2)
      new_item.update!(position: 1)
    end
    

    Using the default behavior, the transaction would fail when executing the
    first UPDATE statement.

    By passing the :deferrable option to the add_unique_key statement in
    migrations, it's possible to defer this check.

    add_unique_key :items, [:position], deferrable: :immediate
    

    Passing deferrable: :immediate does not change the behaviour of the previous example,
    but allows manually deferring the check using SET CONSTRAINTS ALL DEFERRED within a transaction.
    This will cause the unique constraints to be checked after the transaction.

    It's also possible to adjust the default behavior from an immediate
    check (after the statement), to a deferred check (after the transaction):

    add_unique_key :items, [:position], deferrable: :deferred
    

    If you want to change an existing unique index to deferrable, you can use :using_index
    to create deferrable unique constraints.

    add_unique_key :items, deferrable: :deferred, using_index: "index_items_on_position"
    

    Hiroyuki Ishii

  • Remove deprecated Tasks::DatabaseTasks.schema_file_type.

    Rafael Mendonça França

  • Remove deprecated config.active_record.partial_writes.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base config accessors.

    Rafael Mendonça França

  • Remove the :include_replicas argument from configs_for. Use :include_hidden argument instead.

    Eileen M. Uchitelle

  • Allow applications to lookup a config via a custom hash key.

    If you have registered a custom config or want to find configs where the hash matches a specific key, now you can pass config_key to configs_for. For example if you have a db_config with the key vitess you can look up a database configuration hash by matching that key.

    ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary", config_key: :vitess)
    ActiveRecord::Base.configurations.configs_for(env_name: "development", config_key: :vitess)
    

    Eileen M. Uchitelle

  • Allow applications to register a custom database configuration handler.

    Adds a mechanism for registering a custom handler for cases where you want database configurations to respond to custom methods. This is useful for non-Rails database adapters or tools like Vitess that you may want to configure differently from a standard HashConfig or UrlConfig.

    Given the following database YAML we want the animals db to create a CustomConfig object instead while the primary database will be a UrlConfig:

    development:
      primary:
        url: postgres://localhost/primary
      animals:
        url: postgres://localhost/animals
        custom_config:
          sharded: 1
    

    To register a custom handler first make a class that has your custom methods:

    class CustomConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
      def sharded?
        custom_config.fetch("sharded", false)
      end
    
      private
        def custom_config
          configuration_hash.fetch(:custom_config)
        end
    end
    

    Then register the config in an initializer:

    ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
      next unless config.key?(:custom_config)
      CustomConfig.new(env_name, name, url, config)
    end
    

    When the application is booted, configuration hashes with the :custom_config key will be CustomConfig objects and respond to sharded?. Applications must handle the condition in which Active Record should use their custom handler.

    Eileen M. Uchitelle and John Crepezzi

  • ActiveRecord::Base.serialize no longer uses YAML by default.

    YAML isn't particularly performant and can lead to security issues
    if not used carefully.

    Unfortunately there isn't really any good serializers in Ruby's stdlib
    to replace it.

    The obvious choice would be JSON, which is a fine format for this use case,
    however the JSON serializer in Ruby's stdlib isn't strict enough, as it fallback
    to casting unknown types to strings, which could lead to corrupted data.

    Some third party JSON libraries like Oj have a suitable strict mode.

    So it's preferable that users choose a serializer based on their own constraints.

    The original default can be restored by setting config.active_record.default_column_serializer = YAML.

    Jean Boussier

  • ActiveRecord::Base.serialize signature changed.

    Rather than a single positional argument that accepts two possible
    types of values, serialize now accepts two distinct keyword arguments.

    Before:

    serialize :content, JSON
    serialize :backtrace, Array
    

    After:

    serialize :content, coder: JSON
    serialize :backtrace, type: Array
    

    Jean Boussier

  • YAML columns use YAML.safe_dump is available.

    As of psych 5.1.0, YAML.safe_dump can now apply the same permitted
    types restrictions than YAML.safe_load.

    It's preferable to ensure the payload only use allowed types when we first
    try to serialize it, otherwise you may end up with invalid records in the
    database.

    Jean Boussier

  • ActiveRecord::QueryLogs better handle broken encoding.

    It's not uncommon when building queries with BLOB fields to contain
    binary data. Unless the call carefully encode the string in ASCII-8BIT
    it generally end up being encoded in UTF-8, and QueryLogs would
    end up failing on it.

    ActiveRecord::QueryLogs no longer depend on the query to be properly encoded.

    Jean Boussier

  • Fix a bug where ActiveRecord::Generators::ModelGenerator would not respect create_table_migration template overrides.

    rails g model create_books title:string content:text
    

    will now read from the create_table_migration.rb.tt template in the following locations in order:

    lib/templates/active_record/model/create_table_migration.rb
    lib/templates/active_record/migration/create_table_migration.rb
    

    Spencer Neste

  • ActiveRecord::Relation#explain now accepts options.

    For databases and adapters which support them (currently PostgreSQL
    and MySQL), options can be passed to explain to provide more
    detailed query plan analysis:

    Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)
    

    Reid Lynch

  • Multiple Arel::Nodes::SqlLiteral nodes can now be added together to
    form Arel::Nodes::Fragments nodes. This allows joining several pieces
    of SQL.

    Matthew Draper, Ole Friis

  • ActiveRecord::Base#signed_id raises if called on a new record.

    Previously it would return an ID that was not usable, since it was based on id = nil.

    Alex Ghiculescu

  • Allow SQL warnings to be reported.

    Active Record configs can be set to enable SQL warning reporting.

    # Configure action to take when SQL query produces warning
    config.active_record.db_warnings_action = :raise
    
    # Configure allowlist of warnings that should always be ignored
    config.active_record.db_warnings_ignore = [
      /Invalid utf8mb4 character string/,
      "An exact warning message",
    ]
    

    This is supported for the MySQL and PostgreSQL adapters.

    Adrianna Chang, Paarth Madan

  • Add #regroup query method as a short-hand for .unscope(:group).group(fields)

    Example:

    Post.group(:title).regroup(:author)
    # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
    

    Danielius Visockas

  • PostgreSQL adapter method enable_extension now allows parameter to be [schema_name.]<extension_name>
    if the extension must be installed on another schema.

    Example: enable_extension('heroku_ext.hstore')

    Leonardo Luarte

  • Add :include option to add_index.

    Add support for including non-key columns in indexes for PostgreSQL
    with the INCLUDE parameter.

    add_index(:users, :email, include: [:id, :created_at])
    

    will result in:

    CREATE INDEX index_users_on_email USING btree (email) INCLUDE (id, created_at)
    

    Steve Abrams

  • ActiveRecord::Relation’s #any?, #none?, and #one? methods take an optional pattern
    argument, more closely matching their Enumerable equivalents.

    George Claghorn

  • Add ActiveRecord::Base.normalizes for declaring attribute normalizations.

    An attribute normalization is applied when the attribute is assigned or
    updated, and the normalized value will be persisted to the database. The
    normalization is also applied to the corresponding keyword argument of query
    methods, allowing records to be queried using unnormalized values.

    For example:

    class User < ActiveRecord::Base
      normalizes :email, with: -> email { email.strip.downcase }
      normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
    end
    
    user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
    user.email                  # => "cruise-control@example.com"
    
    user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
    user.email                  # => "cruise-control@example.com"
    user.email_before_type_cast # => "cruise-control@example.com"
    
    User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count         # => 1
    User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
    
    User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")         # => true
    User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
    
    User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"
    

    Jonathan Hefner

  • Hide changes to before_committed! callback behaviour behind flag.

    In #46525, behavior around before_committed! callbacks was changed so that callbacks
    would run on every enrolled record in a transaction, not just the first copy of a record.
    This change in behavior is now controlled by a configuration option,
    config.active_record.before_committed_on_all_records. It will be enabled by default on Rails 7.1.

    Adrianna Chang

  • The namespaced_controller Query Log tag now matches the controller format

    For example, a request processed by NameSpaced::UsersController will now log as:

    :controller # "users"
    :namespaced_controller # "name_spaced/users"
    

    Alex Ghiculescu

  • Return only unique ids from ActiveRecord::Calculations#ids

    Updated ActiveRecord::Calculations#ids to only return the unique ids of the base model
    when using eager_load, preload and includes.

    Post.find_by(id: 1).comments.count
    # => 5
    Post.includes(:comments).where(id: 1).pluck(:id)
    # => [1, 1, 1, 1, 1]
    Post.includes(:comments).where(id: 1).ids
    # => [1]
    

    Joshua Young

  • Stop using LOWER() for case-insensitive queries on citext columns

    Previously, LOWER() was added for e.g. uniqueness validations with
    case_sensitive: false.
    It wasn't mentioned in the documentation that the index without LOWER()
    wouldn't be used in this case.

    Phil Pirozhkov

  • Extract #sync_timezone_changes method in AbstractMysqlAdapter to enable subclasses
    to sync database timezone changes without overriding #raw_execute.

    Adrianna Chang, Paarth Madan

  • Do not write additional new lines when dumping sql migration versions

    This change updates the insert_versions_sql function so that the database insert string containing the current database migration versions does not end with two additional new lines.

    Misha Schwartz

  • Fix composed_of value freezing and duplication.

    Previously composite values exhibited two confusing behaviors:

    • When reading a compositve value it'd NOT be frozen, allowing it to get out of sync with its underlying database
      columns.
    • When writing a compositve value the argument would be frozen, potentially confusing the caller.

    Currently, composite values instantiated based on database columns are frozen (addressing the first issue) and
    assigned compositve values are duplicated and the duplicate is frozen (addressing the second issue).

    Greg Navis

  • Fix redundant updates to the column insensitivity cache

    Fixed redundant queries checking column capability for insensitive
    comparison.

    Phil Pirozhkov

  • Allow disabling methods generated by ActiveRecord.enum.

    Alfred Dominic

  • Avoid validating belongs_to association if it has not changed.

    Previously, when updating a record, Active Record will perform an extra query to check for the presence of
    belongs_to associations (if the presence is configured to be mandatory), even if that attribute hasn't changed.

    Currently, only belongs_to-related columns are checked for presence. It is possible to have orphaned records with
    this approach. To avoid this problem, you need to use a foreign key.

    This behavior can be controlled by configuration:

    config.active_record.belongs_to_required_validates_foreign_key = false
    

    and will be disabled by default with config.load_defaults 7.1.

    fatkodima

  • has_one and belongs_to associations now define a reset_association method
    on the owner model (where association is the name of the association). This
    method unloads the cached associate record, if any, and causes the next access
    to query it from the database.

    George Claghorn

  • Allow per attribute setting of YAML permitted classes (safe load) and unsafe load.

    Carlos Palhares

  • Add a build persistence method

    Provides a wrapper for new, to provide feature parity with creates
    ability to create multiple records from an array of hashes, using the
    same notation as the build method on associations.

    Sean Denny

  • Raise on assignment to readonly attributes

    class Post < ActiveRecord::Base
      attr_readonly :content
    end
    Post.create!(content: "cannot be updated")
    post.content # "cannot be updated"
    post.content = "something else" # => ActiveRecord::ReadonlyAttributeError
    

    Previously, assignment would succeed but silently not write to the database.

    This behavior can be controlled by configuration:

    config.active_record.raise_on_assign_to_attr_readonly = true
    

    and will be enabled by default with config.load_defaults 7.1.

    Alex Ghiculescu, Hartley McGuire

  • Allow unscoping of preload and eager_load associations

    Added the ability to unscope preload and eager_load associations just like
    includes, joins, etc. See ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES
    for the full list of supported unscopable scopes.

    query.unscope(:eager_load, :preload).group(:id).select(:id)
    

    David Morehouse

  • Add automatic filtering of encrypted attributes on inspect

    This feature is enabled by default but can be disabled with

    config.active_record.encryption.add_to_filter_parameters = false
    

    Hartley McGuire

  • Clear locking column on #dup

    This change fixes not to duplicate locking_column like id and timestamps.

    car = Car.create!
    car.touch
    car.lock_version #=> 1
    car.dup.lock_version #=> 0
    

    Shouichi Kamiya, Seonggi Yang, Ryohei UEDA

  • Invalidate transaction as early as possible

    After rescuing a TransactionRollbackError exception Rails invalidates transactions earlier in the flow
    allowing the framework to skip issuing the ROLLBACK statement in more cases.
    Only affects adapters that have savepoint_errors_invalidate_transactions? configured as true,
    which at this point is only applicable to the mysql2 adapter.

    Nikita Vasilevsky

  • Allow configuring columns list to be used in SQL queries issued by an ActiveRecord::Base object

    It is now possible to configure columns list that will be used to build an SQL query clauses when
    updating, deleting or reloading an ActiveRecord::Base object

    class Developer < ActiveRecord::Base
      query_constraints :company_id, :id
    end
    developer = Developer.first.update(name: "Bob")
    # => UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
    

    Nikita Vasilevsky

  • Adds validate to foreign keys and check constraints in schema.rb

    Previously, schema.rb would not record if validate: false had been used when adding a foreign key or check
    constraint, so restoring a database from the schema could result in foreign keys or check constraints being
    incorrectly validated.

    Tommy Graves

  • Adapter #execute methods now accept an allow_retry option. When set to true, the SQL statement will be
    retried, up to the database's configured connection_retries value, upon encountering connection-related errors.

    Adrianna Chang

  • Only trigger after_commit :destroy callbacks when a database row is deleted.

    This prevents after_commit :destroy callbacks from being triggered again
    when destroy is called multiple times on the same record.

    Ben Sheldon

  • Fix ciphertext_for for yet-to-be-encrypted values.

    Previously, ciphertext_for returned the cleartext of values that had not
    yet been encrypted, such as with an unpersisted record:

    Post.encrypts :body
    
    post = Post.create!(body: "Hello")
    post.ciphertext_for(:body)
    # => "{\"p\":\"abc..."
    
    post.body = "World"
    post.ciphertext_for(:body)
    # => "World"
    

    Now, ciphertext_for will always return the ciphertext of encrypted
    attributes:

    Post.encrypts :body
    
    post = Post.create!(body: "Hello")
    post.ciphertext_for(:body)
    # => "{\"p\":\"abc..."
    
    post.body = "World"
    post.ciphertext_for(:body)
    # => "{\"p\":\"xyz..."
    

    Jonathan Hefner

  • Fix a bug where using groups and counts with long table names would return incorrect results.

    Shota Toguchi, Yusaku Ono

  • Fix encryption of column default values.

    Previously, encrypted attributes that used column default values appeared to
    be encrypted on create, but were not:

    Book.encrypts :name
    
    book = Book.create!
    book.name
    # => "<untitled>"
    book.name_before_type_cast
    # => "{\"p\":\"abc..."
    book.reload.name_before_type_cast
    # => "<untitled>"
    

    Now, attributes with column default values are encrypted:

    Book.encrypts :name
    
    book = Book.create!
    book.name
    # => "<untitled>"
    book.name_before_type_cast
    # => "{\"p\":\"abc..."
    book.reload.name_before_type_cast
    # => "{\"p\":\"abc..."
    

    Jonathan Hefner

  • Deprecate delegation from Base to connection_handler.

    Calling Base.clear_all_connections!, Base.clear_active_connections!, Base.clear_reloadable_connections! and Base.flush_idle_connections! is deprecated. Please call these methods on the connection handler directly. In future Rails versions, the delegation from Base to the connection_handler will be removed.

    Eileen M. Uchitelle

  • Allow ActiveRecord::QueryMethods#reselect to receive hash values, similar to ActiveRecord::QueryMethods#select

    Sampat Badhe

  • Validate options when managing columns and tables in migrations.

    If an invalid option is passed to a migration method like create_table and add_column, an error will be raised
    instead of the option being silently ignored. Validation of the options will only be applied for new migrations
    that are created.

    Guo Xiang Tan, George Wambold

  • Update query log tags to use the SQLCommenter format by default. See #46179

    To opt out of SQLCommenter-formatted query log tags, set config.active_record.query_log_tags_format = :legacy. By default, this is set to :sqlcommenter.

    Modulitos and Iheanyi

  • Allow any ERB in the database.yml when creating rake tasks.

    Any ERB can be used in database.yml even if it accesses environment
    configurations.

    Deprecates config.active_record.suppress_multiple_database_warning.

    Eike Send

  • Add table to error for duplicate column definitions.

    If a migration defines duplicate columns for a table, the error message
    shows which table it concerns.

    Petrik de Heus

  • Fix erroneous nil default precision on virtual datetime columns.

    Prior to this change, virtual datetime columns did not have the same
    default precision as regular datetime columns, resulting in the following
    being erroneously equivalent:

    t.virtual :name, type: datetime,                 as: "expression"
    t.virtual :name, type: datetime, precision: nil, as: "expression"
    

    This change fixes the default precision lookup, so virtual and regular
    datetime column default precisions match.

    Sam Bostock

  • Use connection from #with_raw_connection in #quote_string.

    This ensures that the string quoting is wrapped in the reconnect and retry logic
    that #with_raw_connection offers.

    Adrianna Chang

  • Add expires_in option to signed_id.

    Shouichi Kamiya

  • Allow applications to set retry deadline for query retries.

    Building on the work done in #44576 and #44591, we extend the logic that automatically
    reconnects database connections to take into account a timeout limit. We won't retry
    a query if a given amount of time has elapsed since the query was first attempted. This
    value defaults to nil, meaning that all retryable queries are retried regardless of time elapsed,
    but this can be changed via the retry_deadline option in the database config.

    Adrianna Chang

  • Fix a case where the query cache can return wrong values. See #46044

    Aaron Patterson

  • Support MySQL's ssl-mode option for MySQLDatabaseTasks.

    Verifying the identity of the database server requires setting the ssl-mode
    option to VERIFY_CA or VERIFY_IDENTITY. This option was previously ignored
    for MySQL database tasks like creating a database and dumping the structure.

    Petrik de Heus

  • Move ActiveRecord::InternalMetadata to an independent object.

    ActiveRecord::InternalMetadata no longer inherits from ActiveRecord::Base and is now an independent object that should be instantiated with a connection. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: ActiveRecord::Base.connection.schema_migration.

    Eileen M. Uchitelle

  • Deprecate quoting ActiveSupport::Duration as an integer

    Using ActiveSupport::Duration as an interpolated bind parameter in a SQL
    string template is deprecated. To avoid this warning, you should explicitly
    convert the duration to a more specific database type. For example, if you
    want to use a duration as an integer number of seconds:

    Record.where("duration = ?", 1.hour.to_i)
    

    If you want to use a duration as an ISO 8601 string:

    Record.where("duration = ?", 1.hour.iso8601)
    

    Aram Greenman

  • Allow QueryMethods#in_order_of to order by a string column name.

    Post.in_order_of("id", [4,2,3,1]).to_a
    Post.joins(:author).in_order_of("authors.name", ["Bob", "Anna", "John"]).to_a
    

    Igor Kasyanchuk

  • Move ActiveRecord::SchemaMigration to an independent object.

    ActiveRecord::SchemaMigration no longer inherits from ActiveRecord::Base and is now an independent object that should be instantiated with a connection. This class is private and should not be used by applications directly. If you want to interact with the schema migrations table, please access it on the connection directly, for example: ActiveRecord::Base.connection.schema_migration.

    Eileen M. Uchitelle

  • Deprecate all_connection_pools and make connection_pool_list more explicit.

    Following on #45924 all_connection_pools is now deprecated. connection_pool_list will either take an explicit role or applications can opt into the new behavior by passing :all.

    Eileen M. Uchitelle

  • Fix connection handler methods to operate on all pools.

    active_connections?, clear_active_connections!, clear_reloadable_connections!, clear_all_connections!, and flush_idle_connections! now operate on all pools by default. Previously they would default to using the current_role or :writing role unless specified.

    Eileen M. Uchitelle

  • Allow ActiveRecord::QueryMethods#select to receive hash values.

    Currently, select might receive only raw sql and symbols to define columns and aliases to select.

    With this change we can provide hash as argument, for example:

    Post.joins(:comments).select(posts: [:id, :title, :created_at], comments: [:id, :body, :author_id])
    #=> "SELECT \"posts\".\"id\", \"posts\".\"title\", \"posts\".\"created_at\", \"comments\".\"id\", \"comments\".\"body\", \"comments\".\"author_id\"
    #   FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
    
    Post.joins(:comments).select(posts: { id: :post_id, title: :post_title }, comments: { id: :comment_id, body: :comment_body })
    #=> "SELECT posts.id as post_id, posts.title as post_title, comments.id as comment_id, comments.body as comment_body
    #    FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
    

    Oleksandr Holubenko, Josef Šimánek, Jean Boussier

  • Adapts virtual attributes on ActiveRecord::Persistence#becomes.

    When source and target classes have a different set of attributes adapts
    attributes such that the extra attributes from target are added.

    class Person < ApplicationRecord
    end
    
    class WebUser < Person
      attribute :is_admin, :boolean
      after_initialize :set_admin
    
      def set_admin
        write_attribute(:is_admin, email =~ /@ourcompany\.com$/)
      end
    end
    
    person = Person.find_by(email: "email@ourcompany.com")
    person.respond_to? :is_admin
    # => false
    person.becomes(WebUser).is_admin?
    # => true
    

    Jacopo Beschi, Sampson Crowley

  • Fix ActiveRecord::QueryMethods#in_order_of to include nils, to match the
    behavior of Enumerable#in_order_of.

    For example, Post.in_order_of(:title, [nil, "foo"]) will now include posts
    with nil titles, the same as Post.all.to_a.in_order_of(:title, [nil, "foo"]).

    fatkodima

  • Optimize add_timestamps to use a single SQL statement.

    add_timestamps :my_table
    

    Now results in the following SQL:

    ALTER TABLE "my_table" ADD COLUMN "created_at" datetime(6) NOT NULL, ADD COLUMN "updated_at" datetime(6) NOT NULL
    

    Iliana Hadzhiatanasova

  • Add drop_enum migration command for PostgreSQL

    This does the inverse of create_enum. Before dropping an enum, ensure you have
    dropped columns that depend on it.

    Alex Ghiculescu

  • Adds support for if_exists option when removing a check constraint.

    The remove_check_constraint method now accepts an if_exists option. If set
    to true an error won't be raised if the check constraint doesn't exist.

    Margaret Parsa and Aditya Bhutani

  • find_or_create_by now try to find a second time if it hits a unicity constraint.

    find_or_create_by always has been inherently racy, either creating multiple
    duplicate records or failing with ActiveRecord::RecordNotUnique depending on
    whether a proper unicity constraint was set.

    create_or_find_by was introduced for this use case, however it's quite wasteful
    when the record is expected to exist most of the time, as INSERT require to send
    more data than SELECT and require more work from the database. Also on some
    databases it can actually consume a primary key increment which is undesirable.

    So for case where most of the time the record is expected to exist, find_or_create_by
    can be made race-condition free by re-trying the find if the create failed
    with ActiveRecord::RecordNotUnique. This assumes that the table has the proper
    unicity constraints, if not, find_or_create_by will still lead to duplicated records.

    Jean Boussier, Alex Kitchens

  • Introduce a simpler constructor API for ActiveRecord database adapters.

    Previously the adapter had to know how to build a new raw connection to
    support reconnect, but also expected to be passed an initial already-
    established connection.

    When manually creating an adapter instance, it will now accept a single
    config hash, and only establish the real connection on demand.

    Matthew Draper

  • Avoid redundant SELECT 1 connection-validation query during DB pool
    checkout when possible.

    If the first query run during a request is known to be idempotent, it can be
    used directly to validate the connection, saving a network round-trip.

    Matthew Draper

  • Automatically reconnect broken database connections when safe, even
    mid-request.

    When an error occurs while attempting to run a known-idempotent query, and
    not inside a transaction, it is safe to immediately reconnect to the
    database server and try again, so this is now the default behavior.

    This new default should always be safe -- to support that, it's consciously
    conservative about which queries are considered idempotent -- but if
    necessary it can be disabled by setting the connection_retries connection
    option to 0.

    Matthew Draper

  • Avoid removing a PostgreSQL extension when there are dependent objects.

    Previously, removing an extension also implicitly removed dependent objects. Now, this will raise an error.

    You can force removing the extension:

    disable_extension :citext, force: :cascade
    

    Fixes #29091.

    fatkodima

  • Allow nested functions as safe SQL string

    Michael Siegfried

  • Allow destroy_association_async_job= to be configured with a class string instead of a constant.

    Defers an autoloading dependency between ActiveRecord::Base and ActiveJob::Base
    and moves the configuration of ActiveRecord::DestroyAssociationAsyncJob
    from ActiveJob to ActiveRecord.

    Deprecates ActiveRecord::ActiveJobRequiredError and now raises a NameError
    if the job class is unloadable or an ActiveRecord::ConfigurationError if
    dependent: :destroy_async is declared on an association but there is no job
    class configured.

    Ben Sheldon

  • Fix ActiveRecord::Store to serialize as a regular Hash

    Previously it would serialize as an ActiveSupport::HashWithIndifferentAccess
    which is wasteful and cause problem with YAML safe_load.

    Jean Boussier

  • Add timestamptz as a time zone aware type for PostgreSQL

    This is required for correctly parsing timestamp with time zone values in your database.

    If you don't want this, you can opt out by adding this initializer:

    ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
    

    Alex Ghiculescu

  • Add new ActiveRecord::Base.generates_token_for API.

    Currently, signed_id fulfills the role of generating tokens for e.g.
    resetting a password. However, signed IDs cannot reflect record state, so
    if a token is intended to be single-use, it must be tracked in a database at
    least until it expires.

    With generates_token_for, a token can embed data from a record. When
    using the token to fetch the record, the data from the token and the current
    data from the record will be compared. If the two do not match, the token
    will be treated as invalid, the same as if it had expired. For example:

    class User < ActiveRecord::Base
      has_secure_password
    
      generates_token_for :password_reset, expires_in: 15.minutes do
        # A password's BCrypt salt changes when the password is updated.
        # By embedding (part of) the salt in a token, the token will
        # expire when the password is updated.
        BCrypt::Password.new(password_digest).salt[-10..]
      end
    end
    
    user = User.first
    token = user.generate_token_for(:password_reset)
    
    User.find_by_token_for(:password_reset, token) # => user
    
    user.update!(password: "new password")
    User.find_by_token_for(:password_reset, token) # => nil
    

    Jonathan Hefner

  • Optimize Active Record batching for whole table iterations.

    Previously, in_batches got all the ids and constructed an IN-based query for each batch.
    When iterating over the whole tables, this approach is not optimal as it loads unneeded ids and
    IN queries with lots of items are slow.

    Now, whole table iterations use range iteration (id >= x AND id <= y) by default which can make iteration
    several times faster. E.g., tested on a PostgreSQL table with 10 million records: querying (253s vs 30s),
    updating (288s vs 124s), deleting (268s vs 83s).

    Only whole table iterations use this style of iteration by default. You can disable this behavior by passing use_ranges: false.
    If you iterate over the table and the only condition is, e.g., archived_at: nil (and only a tiny fraction
    of the records are archived), it makes sense to opt in to this approach:

    Project.where(archived_at: nil).in_batches(use_ranges: true) do |relation|
      # do something
    end
    

    See #45414 for more details.

    fatkodima

  • .with query method added. Construct common table expressions with ease and get ActiveRecord::Relation back.

    Post.with(posts_with_comments: Post.where("comments_count > ?", 0))
    # => ActiveRecord::Relation
    # WITH posts_with_comments AS (SELECT * FROM posts WHERE (comments_count > 0)) SELECT * FROM posts
    

    Vlado Cingel

  • Don't establish a new connection if an identical pool exists already.

    Previously, if establish_connection was called on a class that already had an established connection, the existing connection would be removed regardless of whether it was the same config. Now if a pool is found with the same values as the new connection, the existing connection will be returned instead of creating a new one.

    This has a slight change in behavior if application code is depending on a new connection being established regardless of whether it's identical to an existing connection. If the old behavior is desirable, applications should call ActiveRecord::Base#remove_connection before establishing a new one. Calling establish_connection with a different config works the same way as it did previously.

    Eileen M. Uchitelle

  • Update db:prepare task to load schema when an uninitialized database exists, and dump schema after migrations.

    Ben Sheldon

  • Fix supporting timezone awareness for tsrange and tstzrange array columns.

    # In database migrations
    add_column :shops, :open_hours, :tsrange, array: true
    # In app config
    ActiveRecord::Base.time_zone_aware_types += [:tsrange]
    # In the code times are properly converted to app time zone
    Shop.create!(open_hours: [Time.current..8.hour.from_now])
    

    Wojciech Wnętrzak

  • Introduce strategy pattern for executing migrations.

    By default, migrations will use a strategy object that delegates the method
    to the connection adapter. Consumers can implement custom strategy objects
    to change how their migrations run.

    Adrianna Chang

  • Add adapter option disallowing foreign keys

    This adds a new option to be added to database.yml which enables skipping
    foreign key constraints usage even if the underlying database supports them.

    Usage:

    development:
        <<: *default
        database: storage/development.sqlite3
        foreign_keys: false
    

    Paulo Barros

  • Add configurable deprecation warning for singular associations

    This adds a deprecation warning when using the plural name of a singular associations in where.
    It is possible to opt into the new more performant behavior with config.active_record.allow_deprecated_singular_associations_name = false

    Adam Hess

  • Run transactional callbacks on the freshest instance to save a given
    record within a transaction.

    When multiple Active Record instances change the same record within a
    transaction, Rails runs after_commit or after_rollback callbacks for
    only one of them. config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
    was added to specify how Rails chooses which instance receives the
    callbacks. The framework defaults were changed to use the new logic.

    When config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
    is true, transactional callbacks are run on the first instance to save,
    even though its instance state may be stale.

    When it is false, which is the new framework default starting with version
    7.1, transactional callbacks are run on the instances with the freshest
    instance state. Those instances are chosen as follows:

    • In general, run transactional callbacks on the last instance to save a
      given record within the transaction.
    • There are two exceptions:
      • If the record is created within the transaction, then updated by
        another instance, after_create_commit callbacks will be run on the
        second instance. This is instead of the after_update_commit
        callbacks that would naively be run based on that instance’s state.
      • If the record is destroyed within the transaction, then
        after_destroy_commit callbacks will be fired on the last destroyed
        instance, even if a stale instance subsequently performed an update
        (which will have affected 0 rows).

    Cameron Bothner and Mitch Vollebregt

  • Enable strict strings mode for SQLite3Adapter.

    Configures SQLite with a strict strings mode, which disables double-quoted string literals.

    SQLite has some quirks around double-quoted string literals.
    It first tries to consider double-quoted strings as identifier names, but if they don't exist
    it then considers them as string literals. Because of this, typos can silently go unnoticed.
    For example, it is possible to create an index for a non existing column.
    See SQLite documentation for more details.

    If you don't want this behavior, you can disable it via:

    # config/application.rb
    config.active_record.sqlite3_adapter_strict_strings_by_default = false
    

    Fixes #27782.

    fatkodima, Jean Boussier

  • Resolve issue where a relation cache_version could be left stale.

    Previously, when reset was called on a relation object it did not reset the cache_versions
    ivar. This led to a confusing situation where despite having the correct data the relation
    still reported a stale cache_version.

    Usage:

    developers = Developer.all
    developers.cache_version
    
    Developer.update_all(updated_at: Time.now.utc + 1.second)
    
    developers.cache_version # Stale cache_version
    developers.reset
    developers.cache_version # Returns the current correct cache_version
    

    Fixes #45341.

    Austen Madden

  • Add support for exclusion constraints (PostgreSQL-only).

    add_exclusion_constraint :invoices, "daterange(start_date, end_date) WITH &&", using: :gist, name: "invoices_date_overlap"
    remove_exclusion_constraint :invoices, name: "invoices_date_overlap"
    

    See PostgreSQL's CREATE TABLE ... EXCLUDE ... documentation for more on exclusion constraints.

    Alex Robbin

  • change_column_null raises if a non-boolean argument is provided

    Previously if you provided a non-boolean argument, change_column_null would
    treat it as truthy and make your column nullable. This could be surprising, so now
    the input must be either true or false.

    change_column_null :table, :column, true # good
    change_column_null :table, :column, false # good
    change_column_null :table, :column, from: true, to: false # raises (previously this made the column nullable)
    

    Alex Ghiculescu

  • Enforce limit on table names length.

    Fixes #45130.

    fatkodima

  • Adjust the minimum MariaDB version for check constraints support.

    Eddie Lebow

  • Fix Hstore deserialize regression.

    edsharp

  • Add validity for PostgreSQL indexes.

    connection.index_exists?(:users, :email, valid: true)
    connection.indexes(:users).select(&:valid?)
    

    fatkodima

  • Fix eager loading for models without primary keys.

    Anmol Chopra, Matt Lawrence, and Jonathan Hefner

  • Avoid validating a unique field if it has not changed and is backed by a unique index.

    Previously, when saving a record, Active Record will perform an extra query to check for the
    uniqueness of each attribute having a uniqueness validation, even if that attribute hasn't changed.
    If the database has the corresponding unique index, then this validation can never fail for persisted
    records, and we could safely skip it.

    fatkodima

  • Stop setting sql_auto_is_null

    Since version 5.5 the default has been off, we no longer have to manually turn it off.

    Adam Hess

  • Fix touch to raise an error for readonly columns.

    fatkodima

  • Add ability to ignore tables by regexp for SQL schema dumps.

    ActiveRecord::SchemaDumper.ignore_tables = [/^_/]
    

    fatkodima

  • Avoid queries when performing calculations on contradictory relations.

    Previously calculations would make a query even when passed a
    contradiction, such as User.where(id: []).count. We no longer perform a
    query in that scenario.

    This applies to the following calculations: count, sum, average,
    minimum and maximum

    Luan Vieira, John Hawthorn and Daniel Colson

  • Allow using aliased attributes with insert_all/upsert_all.

    class Book < ApplicationRecord
      alias_attribute :title, :name
    end
    
    Book.insert_all [{ title: "Remote", author_id: 1 }], returning: :title
    

    fatkodima

  • Support encrypted attributes on columns with default db values.

    This adds support for encrypted attributes defined on columns with default values.
    It will encrypt those values at creation time. Before, it would raise an
    error unless config.active_record.encryption.support_unencrypted_data was true.

    Jorge Manrubia and Dima Fatko

  • Allow overriding reading_request? in DatabaseSelector::Resolver

    The default implementation checks if a request is a get? or head?,
    but you can now change it to anything you like. If the method returns true,
    Resolver#read gets called meaning the request could be served by the
    replica database.

    Alex Ghiculescu

  • Remove ActiveRecord.legacy_connection_handling.

    Eileen M. Uchitelle

  • rails db:schema:{dump,load} now checks ENV["SCHEMA_FORMAT"] before config

    Since rails db:structure:{dump,load} was deprecated there wasn't a simple
    way to dump a schema to both SQL and Ruby formats. You can now do this with
    an environment variable. For example:

    SCHEMA_FORMAT=sql rake db:schema:dump
    

    Alex Ghiculescu

  • Fixed MariaDB default function support.

    Defaults would be written wrong in "db/schema.rb" and not work correctly
    if using db:schema:load. Further more the function name would be
    added as string content when saving new records.

    kaspernj

  • Add active_record.destroy_association_async_batch_size configuration

    This allows applications to specify the maximum number of records that will
    be destroyed in a single background job by the dependent: :destroy_async
    association option. By default, the current behavior will remain the same:
    when a parent record is destroyed, all dependent records will be destroyed
    in a single background job. If the number of dependent records is greater
    than this configuration, the records will be destroyed in multiple
    background jobs.

    Nick Holden

  • Fix remove_foreign_key with :if_exists option when foreign key actually exists.

    fatkodima

  • Remove --no-comments flag in structure dumps for PostgreSQL

    This broke some apps that used custom schema comments. If you don't want
    comments in your structure dump, you can use:

    ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
    

    Alex Ghiculescu

  • Reduce the memory footprint of fixtures accessors.

    Until now fixtures accessors were eagerly defined using define_method.
    So the memory usage was directly dependent of the number of fixtures and
    test suites.

    Instead fixtures accessors are now implemented with method_missing,
    so they incur much less memory and CPU overhead.

    Jean Boussier

  • Fix config.active_record.destroy_association_async_job configuration

    config.active_record.destroy_association_async_job should allow
    applications to specify the job that will be used to destroy associated
    records in the background for has_many associations with the
    dependent: :destroy_async option. Previously, that was ignored, which
    meant the default ActiveRecord::DestroyAssociationAsyncJob always
    destroyed records in the background.

    Nick Holden

  • Fix change_column_comment to preserve column's AUTO_INCREMENT in the MySQL adapter

    fatkodima

  • Fix quoting of ActiveSupport::Duration and Rational numbers in the MySQL adapter.

    Kevin McPhillips

  • Allow column name with COLLATE (e.g., title COLLATE "C") as safe SQL string

    Shugo Maeda

  • Permit underscores in the VERSION argument to database rake tasks.

    Eddie Lebow

  • Reversed the order of INSERT statements in structure.sql dumps

    This should decrease the likelihood of merge conflicts. New migrations
    will now be added at the top of the list.

    For existing apps, there will be a large diff the next time structure.sql
    is generated.

    Alex Ghiculescu, Matt Larraz

  • Fix PG.connect keyword arguments deprecation warning on ruby 2.7

    Fixes #44307.

    Nikita Vasilevsky

  • Fix dropping DB connections after serialization failures and deadlocks.

    Prior to 6.1.4, serialization failures and deadlocks caused rollbacks to be
    issued for both real transactions and savepoints. This breaks MySQL which
    disallows rollbacks of savepoints following a deadlock.

    6.1.4 removed these rollbacks, for both transactions and savepoints, causing
    the DB connection to be left in an unknown state and thus discarded.

    These rollbacks are now restored, except for savepoints on MySQL.

    Thomas Morgan

  • Make ActiveRecord::ConnectionPool Fiber-safe

    When ActiveSupport::IsolatedExecutionState.isolation_level is set to :fiber,
    the connection pool now supports multiple Fibers from the same Thread checking
    out connections from the pool.

    Alex Matchneer

  • Add update_attribute! to ActiveRecord::Persistence

    Similar to update_attribute, but raises ActiveRecord::RecordNotSaved when a before_* callback throws :abort.

    class Topic < ActiveRecord::Base
      before_save :check_title
    
      def check_title
        throw(:abort) if title == "abort"
      end
    end
    
    topic = Topic.create(title: "Test Title")
    # #=> #<Topic title: "Test Title">
    topic.update_attribute!(:title, "Another Title")
    # #=> #<Topic title: "Another Title">
    topic.update_attribute!(:title, "abort")
    # raises ActiveRecord::RecordNotSaved
    

    Drew Tempelmeyer

  • Avoid loading every record in ActiveRecord::Relation#pretty_print

    # Before
    pp Foo.all # Loads the whole table.
    
    # After
    pp Foo.all # Shows 10 items and an ellipsis.
    

    Ulysse Buonomo

  • Change QueryMethods#in_order_of to drop records not listed in values.

    in_order_of now filters down to the values provided, to match the behavior of the Enumerable version.

    Kevin Newton

  • Allow named expression indexes to be revertible.

    Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.

    add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
    

    Fixes #43331.

    Oliver Günther

  • Fix incorrect argument in PostgreSQL structure dump tasks.

    Updating the --no-comment argument added in Rails 7 to the correct --no-comments argument.

    Alex Dent

  • Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.

    Reference/belongs_to in migrations with version 6.0 were creating columns as
    bigint instead of integer for the SQLite Adapter.

    Marcelo Lauxen

  • Fix QueryMethods#in_order_of to handle empty order list.

    Post.in_order_of(:id, []).to_a
    

    Also more explicitly set the column as secondary order, so that any other
    value is still ordered.

    Jean Boussier

  • Fix quoting of column aliases generated by calculation methods.

    Since the alias is derived from the table name, we can't assume the result
    is a valid identifier.

    class Test < ActiveRecord::Base
      self.table_name = '1abc'
    end
    Test.group(:id).count
    # syntax error at or near "1" (ActiveRecord::StatementInvalid)
    # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
    

    Jean Boussier

  • Add authenticate_by when using has_secure_password.

    authenticate_by is intended to replace code like the following, which
    returns early when a user with a matching email is not found:

    User.find_by(email: "...")&.authenticate("...")
    

    Such code is vulnerable to timing-based enumeration attacks, wherein an
    attacker can determine if a user account with a given email exists. After
    confirming that an account exists, the attacker can try passwords associated
    with that email address from other leaked databases, in case the user
    re-used a password across multiple sites (a common practice). Additionally,
    knowing an account email address allows the attacker to attempt a targeted
    phishing ("spear phishing") attack.

    authenticate_by addresses the vulnerability by taking the same amount of
    time regardless of whether a user with a matching email is found:

    User.authenticate_by(email: "...", password: "...")
    

    Jonathan Hefner

Action View

  • Fix simple_format with blank wrapper_tag option returns plain html tag

    By default simple_format method returns the text wrapped with <p>. But if we explicitly specify
    the wrapper_tag: nil in the options, it returns the text wrapped with <></> tag.

    Before:

    simple_format("Hello World", {},  { wrapper_tag: nil })
    # <>Hello World</>
    

    After:

    simple_format("Hello World", {},  { wrapper_tag: nil })
    # <p>Hello World</p>
    

    Akhil G Krishnan, Junichi Ito

  • Don't double-encode nested field_id and field_name index values

    Pass index: @options as a default keyword argument to field_id and
    field_name view helper methods.

    Sean Doyle

  • Allow opting in/out of Link preload headers when calling stylesheet_link_tag or javascript_include_tag

    # will exclude header, even if setting is enabled:
    javascript_include_tag("http://example.com/all.js", preload_links_header: false)
    
    # will include header, even if setting is disabled:
    stylesheet_link_tag("http://example.com/all.js", preload_links_header: true)
    

    Alex Ghiculescu

  • Stop generating Link preload headers once it has reached 1KB.

    Some proxies have trouble handling large headers, but more importantly preload links
    have diminishing returns so it's preferable not to go overboard with them.

    If tighter control is needed, it's recommended to disable automatic generation of preloads
    and to generate them manually from the controller or from a middleware.

    Jean Boussier

  • simple_format helper now handles a :sanitize_options - any extra options you want appending to the sanitize.

    Before:

      simple_format("<a target=\"_blank\" href=\"http://example.com\">Continue</a>")
      # => "<p><a href=\"http://example.com\">Continue</a></p>"
    

    After:

      simple_format("<a target=\"_blank\" href=\"http://example.com\">Continue</a>", {}, { sanitize_options: { attributes: %w[target href] } })
      # => "<p><a target=\"_blank\" href=\"http://example.com\">Continue</a></p>"
    

    Andrei Andriichuk

  • Add support for HTML5 standards-compliant sanitizers, and default to Rails::HTML5::Sanitizer
    in the Rails 7.1 configuration if it is supported.

    Action View's HTML sanitizers can be configured by setting
    config.action_view.sanitizer_vendor. Supported values are Rails::HTML4::Sanitizer or
    Rails::HTML5::Sanitizer.

    The Rails 7.1 configuration will set this to Rails::HTML5::Sanitizer when it is supported, and
    fall back to Rails::HTML4::Sanitizer. Previous configurations default to
    Rails::HTML4::Sanitizer.

    Mike Dalessio

  • config.dom_testing_default_html_version controls the HTML parser used by
    ActionView::TestCase#document_root_element, which creates the DOM used by the assertions in
    Rails::Dom::Testing.

    The Rails 7.1 default configuration opts into the HTML5 parser when it is supported, to better
    represent what the DOM would be in a browser user agent. Previously this test helper always used
    Nokogiri's HTML4 parser.

    Mike Dalessio

  • Add support for the HTML picture tag. It supports passing a String, an Array or a Block.
    Supports passing properties directly to the img tag via the :image key.
    Since the picture tag requires an img tag, the last element you provide will be used for the img tag.
    For complete control over the picture tag, a block can be passed, which will populate the contents of the tag accordingly.

    Can be used like this for a single source:

    <%= picture_tag("picture.webp") %>
    

    which will generate the following:

    <picture>
        <img src="/images/picture.webp" />
    </picture>
    

    For multiple sources:

    <%= picture_tag("picture.webp", "picture.png", :class => "mt-2", :image => { alt: "Image", class: "responsive-img" }) %>
    

    will generate:

    <picture class="mt-2">
        <source srcset="/images/picture.webp" />
        <source srcset="/images/picture.png" />
        <img alt="Image" class="responsive-img" src="/images/picture.png" />
    </picture>
    

    Full control via a block:

    <%= picture_tag(:class => "my-class") do %>
        <%= tag(:source, :srcset => image_path("picture.webp")) %>
        <%= tag(:source, :srcset => image_path("picture.png")) %>
        <%= image_tag("picture.png", :alt => "Image") %>
    <% end %>
    

    will generate:

    <picture class="my-class">
        <source srcset="/images/picture.webp" />
        <source srcset="/images/picture.png" />
        <img alt="Image" src="/images/picture.png" />
    </picture>
    

    Juan Pablo Balarini

  • Remove deprecated support to passing instance variables as locals to partials.

    Rafael Mendonça França

  • Remove deprecated constant ActionView::Path.

    Rafael Mendonça França

  • Guard token_list calls from escaping HTML too often

    Sean Doyle

  • select can now be called with a single hash containing options and some HTML options

    Previously this would not work as expected:

    <%= select :post, :author, authors, required: true %>
    

    Instead you needed to do this:

    <%= select :post, :author, authors, {}, required: true %>
    

    Now, either form is accepted, for the following HTML attributes: required, multiple, size.

    Alex Ghiculescu

  • Datetime form helpers (time_field, date_field, datetime_field, week_field, month_field) now accept an instance of Time

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.0.8

Active Support

  • Fix TimeWithZone still using deprecated #to_s when ENV or config to
    disable it are set.

    Hartley McGuire

  • Fix CacheStore#write_multi when using a distributed Redis cache with a connection pool.

    Fixes #48938.

    Jonathan del Strother

Active Model

  • No changes.

Active Record

  • Fix change_column not setting precision: 6 on datetime columns when
    using 7.0+ Migrations and SQLite.

    Hartley McGuire

  • Fix unscope is not working in specific case

    Before:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
    
    

    After:

    Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
    

    Fixes #48094.

    Kazuya Hatanaka

  • Fix associations to a STI model including a class_name parameter

    class Product < ApplicationRecord
      has_many :requests, as: :requestable, class_name: "ProductRequest", dependent: :destroy
    end
    
    # STI tables
    class Request < ApplicationRecord
      belongs_to :requestable, polymorphic: true
    
      validate :request_type, presence: true
    end
    
    class ProductRequest < Request
      belongs_to :user
    end
    

    Accessing such association would lead to:

    table_metadata.rb:22:in `has_column?': undefined method `key?' for nil:NilClass (NoMethodError)
    

    Romain Filinto

  • Fix change_table setting datetime precision for 6.1 Migrations

    Hartley McGuire

  • Fix change_column setting datetime precision for 6.1 Migrations

    Hartley McGuire

Action View

  • Fix form_for missing the hidden _method input for models with a
    namespaced route.

    Hartley McGuire

  • Fix render collection: @records, cache: true inside jbuilder templates

    The previous fix that shipped in 7.0.7 assumed template fragments are always strings,
    this isn't true with jbuilder.

    Jean Boussier

Action Pack

  • Fix HostAuthorization potentially displaying the value of the
    X_FORWARDED_HOST header when the HTTP_HOST header is being blocked.

    Hartley McGuire, Daniel Schlosser

Active Job

  • Fix Active Job log message to correctly report a job failed to enqueue
    when the adapter raises an ActiveJob::EnqueueError.

    Ben Sheldon

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Omit webdrivers gem dependency from Gemfile template

    Sean Doyle

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.0.7.2

No changes between this and 7.0.7.2. This release was just to fix file permissions in the previous release.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails -

No changes between this and 6.1.7.5. This release was just to fix file permissions in the previous release.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails - 7.0.7.1 release

Active Support

  • Use a temporary file for storing unencrypted files while editing

    [CVE-2023-38037]

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails - 6.1.7.5 Release

Active Support

  • Use a temporary file for storing unencrypted files while editing

    [CVE-2023-38037]

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails - 7.0.7

Active Support

  • Fix Cache::NullStore with local caching for repeated reads.

    fatkodima

  • Fix to_s with no arguments not respecting custom :default formats

    Hartley McGuire

  • Fix ActiveSupport::Inflector.humanize(nil) raising NoMethodError: undefined method `end_with?' for nil:NilClass.

    James Robinson

  • Fix Enumerable#sum for Enumerator#lazy.

    fatkodima, Matthew Draper, Jonathan Hefner

  • Improve error message when EventedFileUpdateChecker is used without a
    compatible version of the Listen gem

    Hartley McGuire

Active Model

  • Error.full_message now strips ":base" from the message.

    zzak

  • Add a load hook for ActiveModel::Model (named active_model) to match the load hook for
    ActiveRecord::Base and allow for overriding aspects of the ActiveModel::Model class.

Active Record

  • Restores functionality to the missing method when using enums and fixes.

    paulreece

  • Fix StatementCache::Substitute with serialized type.

    ywenc

  • Fix :db_runtime on notification payload when application have multiple databases.

    Eileen M. Uchitelle

  • Correctly dump check constraints for MySQL 8.0.16+.

    Steve Hill

  • Fix ActiveRecord::QueryMethods#in_order_of to include nils, to match the
    behavior of Enumerable#in_order_of.

    For example, Post.in_order_of(:title, [nil, "foo"]) will now include posts
    with nil titles, the same as Post.all.to_a.in_order_of(:title, [nil, "foo"]).

    fatkodima

  • Revert "Fix autosave associations with validations added on :base of the associated objects."

    This change intended to remove the :base attribute from the message,
    but broke many assumptions which key these errors were stored.

    zzak

  • Fix #previously_new_record? to return true for destroyed records.

    Before, if a record was created and then destroyed, #previously_new_record? would return true.
    Now, any UPDATE or DELETE to a record is considered a change, and will result in #previously_new_record?
    returning false.

    Adrianna Chang

  • Revert breaking changes to has_one relationship deleting the old record before the new one is validated.

    zzak

  • Fix support for Active Record instances being uses in queries.

    As of 7.0.5, query arguments were deep duped to avoid mutations impacting
    the query cache, but this had the adverse effect to clearing the primary key when
    the query argument contained an ActiveRecord::Base instance.

    This broke the noticed gem.

    Jean Boussier

Action View

  • Fix render collection: @records, cache: true to cache fragments as bare strings

    Previously it would incorrectly cache them as Action View buffers.

    Jean Boussier

  • Don't double-encode nested field_id and field_name index values

    Pass index: @options as a default keyword argument to field_id and
    field_name view helper methods.

    Sean Doyle

Action Pack

  • No changes.

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

  • Update default scaffold templates to set 303 (See Other) as status code
    on redirect for the update action for XHR requests other than GET or POST
    to avoid issues (e.g browsers trying to follow the redirect using the
    original request method resulting in double PATCH/PUT)

    Guillermo Iguaran

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - 7.0.6

Active Support

  • Fix EncryptedConfiguration returning incorrect values for some Hash
    methods

    Hartley McGuire

  • Fix arguments being destructed Enumerable#many? with block.

    Andrew Novoselac

  • Fix humanize for strings ending with id.

    fatkodima

Active Model

  • No changes.

Active Record

  • Fix autosave associations with validations added on :base of the associated objects.

    fatkodima

  • Fix result with anonymous PostgreSQL columns of different type from json.

    Oleksandr Avoiants

  • Preserve timestamp when setting an ActiveSupport::TimeWithZone value to timestamptz attribute.

    fatkodima

  • Fix where on association with has_one/has_many polymorphic relations.

    Before:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
    

    Later:

    Treasure.where(price_estimates: PriceEstimate.all)
    #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
    

    Lázaro Nixon

  • Fix decrementing counter caches on optimistically locked record deletion

    fatkodima

  • Ensure binary-destined values have binary encoding during type cast.

    Matthew Draper

  • Preserve existing column default functions when altering table in SQLite.

    fatkodima

  • Remove table alias added when using where.missing or where.associated.

    fatkodima

  • Fix Enumerable#in_order_of to only flatten first level to preserve nesting.

    Miha Rekar

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • Fix error Active Job passed class with permitted?.

    Alex Baldwin

Action Mailer

  • No changes.

Action Cable

  • Fix Action Cable Redis configuration with sentinels.

    Dmitriy Ivliev

Active Storage

  • Fix retrieving rotation value from FFmpeg on version 5.0+.

    In FFmpeg version 5.0+ the rotation value has been removed from tags.
    Instead the value can be found in side_data_list. Along with
    this update it's possible to have values of -90, -270 to denote the video
    has been rotated.

    Haroon Ahmed

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • Avoid escaping paths when editing credentials.

    Jonathan Hefner

- Ruby
Published by rafaelfranca over 2 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v7.0.5.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Raise an exception if illegal characters are provide to redirect_to
    [CVE-2023-28362]

    Zack Deveau

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.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.1.7.4

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Raise an exception if illegal characters are provide to redirect_to
    [CVE-2023-28362]

    Zack Deveau

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.

- Ruby
Published by tenderlove over 2 years ago

https://github.com/rails/rails - v7.0.5

Active Support

  • Fixes TimeWithZone ArgumentError.

    Niklas Häusele

Active Model

  • No changes.

Active Record

  • Type cast #attribute_changed? :from and :to options.

    Andrew Novoselac

  • Fix index_exists? when column is an array.

    Eileen M. Uchitelle

  • Handle Date objects for PostgreSQL timestamptz columns.

    Alex Ghiculescu

  • Fix collation for changing column to non-string.

    Hartley McGuire

  • Map through subtype in PostgreSQL::OID::Array.

    Jonathan Hefner

  • Store correct environment in internal_metadata when run rails db:prepare.

    fatkodima

  • Make sure ActiveRecord::Relation#sum works with objects that implement #coerce without deprecation.

    Alex Ghiculescu

  • Fix retrieving foreign keys referencing tables named like keywords in PostgreSQL and MySQL.

    fatkodima

  • Support UUIDs in Disable Joins.

    Samuel Cochran

  • Fix Active Record's explain for queries starting with comments.

    fatkodima

  • Fix incorrectly preloading through association records when middle association has been loaded.

    Joshua Young

  • Fix where.missing and where.associated for parent/child associations.

    fatkodima

  • Fix Enumerable#in_order_of to preserve duplicates.

    fatkodima

  • Fix autoincrement on primary key for mysql.

    Eileen M. Uchitelle

  • Restore ability to redefine column in create_table for Rails 5.2 migrations.

    fatkodima

  • Fix schema cache dumping of virtual columns.

    fatkodima

  • Fix Active Record grouped calculations on joined tables on column present in both tables.

    fatkodima

  • Fix mutation detection for serialized attributes backed by binary columns.

    Jean Boussier

  • Fix a bug where using groups and counts with long table names would return incorrect results.

    Shota Toguchi, Yusaku Ono

  • Fix erroneous nil default precision on virtual datetime columns.

    Prior to this change, virtual datetime columns did not have the same
    default precision as regular datetime columns, resulting in the following
    being erroneously equivalent:

    t.virtual :name, type: datetime,                 as: "expression"
    t.virtual :name, type: datetime, precision: nil, as: "expression"
    

    This change fixes the default precision lookup, so virtual and regular
    datetime column default precisions match.

    Sam Bostock

  • Fix a case where the query cache can return wrong values. See #46044

    Aaron Patterson

Action View

  • FormBuilder#id finds id set by form_for and form_with.

    Matt Polito

  • Allow all available locales for template lookups.

    Ben Dilley

  • Choices of select can optionally contain html attributes as the last element
    of the child arrays when using grouped/nested collections

    <%= form.select :foo, [["North America", [["United States","US"],["Canada","CA"]], { disabled: "disabled" }]] %>
    # => <select><optgroup label="North America" disabled="disabled"><option value="US">United States</option><option value="CA">Canada</option></optgroup></select>
    

    Chris Gunther

Action Pack

  • Do not return CSP headers for 304 Not Modified responses.

    Tobias Kraze

  • Fix EtagWithFlash when there is no Flash middleware available.

    fatkodima

  • Fix content-type header with send_stream.

    Elliot Crosby-McCullough

  • Address Selenium :capabilities deprecation warning.

    Ron Shinall

  • Fix cookie domain for domain: all on two letter single level TLD.

    John Hawthorn

  • Don't double log the controller, action, or namespaced_controller when using ActiveRecord::QueryLog

    Previously if you set config.active_record.query_log_tags to an array that included
    :controller, :namespaced_controller, or :action, that item would get logged twice.
    This bug has been fixed.

    Alex Ghiculescu

  • Rescue EOFError exception from rack on a multipart request.

    Nikita Vasilevsky

  • Rescue JSON::ParserError in Cookies json deserializer to discards marshal dumps:

    Without this change, if action_dispatch.cookies_serializer is set to :json and
    the app tries to read a :marshal serialized cookie, it would error out which wouldn't
    clear the cookie and force app users to manually clear it in their browser.

    (See #45127 for original bug discussion)

    Nathan Bardoux

Active Job

  • Make delayed job display_name failsafe.

    codez

  • Don't double log the job when using ActiveRecord::QueryLog

    Previously if you set config.active_record.query_log_tags to an array that included
    :job, the job name would get logged twice. This bug has been fixed.

    Alex Ghiculescu

Action Mailer

  • No changes.

Action Cable

  • Restore Action Cable Redis pub/sub listener on connection failure.

    Vladimir Dementyev

Active Storage

  • No changes.

Action Mailbox

  • No changes.

Action Text

  • Fix ActionText::Attachable#as_json.

    Alexandre Ruban

Railties

  • Add puma app server to Gemfile in order to start test/dummy.

    Donapieppo

  • Rails console now disables IRB's autocompletion feature in production by default.

    Setting IRB_USE_AUTOCOMPLETE=true can override this default.

    Stan Lo

  • Send 303 See Other status code back for the destroy action on newly generated
    scaffold controllers.

    Tony Drake

- Ruby
Published by rafaelfranca almost 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.1.7.3

Active Support

  • Implement SafeBuffer#bytesplice

    [CVE-2023-28120]

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Ignore certain data-* attributes in rails-ujs when element is contenteditable

    [CVE-2023-23913]

Action Pack

  • No changes.

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.

- Ruby
Published by jhawthorn almost 3 years ago

https://github.com/rails/rails -

Active Support

  • Implement SafeBuffer#bytesplice

    [CVE-2023-28120]

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Ignore certain data-* attributes in rails-ujs when element is contenteditable

    [CVE-2023-23913]

Action Pack

  • No changes.

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.

- Ruby
Published by jhawthorn almost 3 years ago

https://github.com/rails/rails -

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix domain: :all for two letter TLD

    This fixes a compatibility issue introduced in our previous security
    release when using domain: :all with a two letter but single level top
    level domain domain (like .ca, rather than .co.uk).

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.

- Ruby
Published by jhawthorn about 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.1.7.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix domain: :all for two letter TLD

    This fixes a compatibility issue introduced in our previous security
    release when using domain: :all with a two letter but single level top
    level domain domain (like .ca, rather than .co.uk).

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.

- Ruby
Published by jhawthorn about 3 years ago

https://github.com/rails/rails -

This is a security release. More information is available in our security announcements forum: https://discuss.rubyonrails.org/c/security-announcements/9

Active Support

  • Avoid regex backtracking in Inflector.underscore

    [CVE-2023-22796]

Active Model

  • No changes.

Active Record

  • Make sanitize_as_sql_comment more strict

    Though this method was likely never meant to take user input, it was
    attempting sanitization. That sanitization could be bypassed with
    carefully crafted input.

    This commit makes the sanitization more robust by replacing any
    occurrances of "/" or "/" with "/ " or " /". It also performs a
    first pass to remove one surrounding comment to avoid compatibility
    issues for users relying on the existing removal.

    This also clarifies in the documentation of annotate that it should not
    be provided user input.

    [CVE-2023-22794]

  • Added integer width check to PostgreSQL::Quoting

    Given a value outside the range for a 64bit signed integer type
    PostgreSQL will treat the column type as numeric. Comparing
    integer values against numeric values can result in a slow
    sequential scan.

    This behavior is configurable via
    ActiveRecord::Base.raise_int_wider_than_64bit which defaults to true.

    [CVE-2022-44566]

Action View

  • No changes.

Action Pack

  • Fix sec issue with _url_host_allowed?

    Disallow certain strings from _url_host_allowed? to avoid a redirect
    to malicious sites.

    [CVE-2023-22797]

  • Avoid regex backtracking on If-None-Match header

    [CVE-2023-22795]

  • Use string#split instead of regex for domain parts

    [CVE-2023-22792]

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.

- Ruby
Published by jhawthorn about 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.1.7.1

Active Support

  • Avoid regex backtracking in Inflector.underscore

    [CVE-2023-22796]

Active Model

  • No changes.

Active Record

  • Make sanitize_as_sql_comment more strict

    Though this method was likely never meant to take user input, it was
    attempting sanitization. That sanitization could be bypassed with
    carefully crafted input.

    This commit makes the sanitization more robust by replacing any
    occurrances of "/" or "/" with "/ " or " /". It also performs a
    first pass to remove one surrounding comment to avoid compatibility
    issues for users relying on the existing removal.

    This also clarifies in the documentation of annotate that it should not
    be provided user input.

    [CVE-2023-22794]

  • Added integer width check to PostgreSQL::Quoting

    Given a value outside the range for a 64bit signed integer type
    PostgreSQL will treat the column type as numeric. Comparing
    integer values against numeric values can result in a slow
    sequential scan.

    This behavior is configurable via
    ActiveRecord::Base.raise_int_wider_than_64bit which defaults to true.

    [CVE-2022-44566]

Action View

  • No changes.

Action Pack

  • Avoid regex backtracking on If-None-Match header

    [CVE-2023-22795]

  • Use string#split instead of regex for domain parts

    [CVE-2023-22792]

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.

- Ruby
Published by jhawthorn about 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.0.6.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Make sanitize_as_sql_comment more strict

    Though this method was likely never meant to take user input, it was
    attempting sanitization. That sanitization could be bypassed with
    carefully crafted input.

    This commit makes the sanitization more robust by replacing any
    occurrances of "/" or "/" with "/ " or " /". It also performs a
    first pass to remove one surrounding comment to avoid compatibility
    issues for users relying on the existing removal.

    This also clarifies in the documentation of annotate that it should not
    be provided user input.

    [CVE-2023-22794]

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by jhawthorn about 3 years ago

https://github.com/rails/rails - 7.0.3.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Change ActiveRecord::Coders::YAMLColumn default to safe_load

    This adds two new configuration options The configuration options are as
    follows:

    • config.active_storage.use_yaml_unsafe_load

    When set to true, this configuration option tells Rails to use the old
    "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
    the possible escalation vulnerability in place. Setting this option to true
    is not recommended, but can aid in upgrading.

    • config.active_record.yaml_column_permitted_classes

    The "safe YAML" loading method does not allow all classes to be deserialized
    by default. This option allows you to specify classes deemed "safe" in your
    application. For example, if your application uses Symbol and Time in
    serialized data, you can add Symbol and Time to the allowed list as follows:

    config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
    

    [CVE-2022-32224]

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by rafaelfranca over 3 years ago

https://github.com/rails/rails - 6.1.6.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Change ActiveRecord::Coders::YAMLColumn default to safe_load

    This adds two new configuration options The configuration options are as
    follows:

    • config.active_storage.use_yaml_unsafe_load

    When set to true, this configuration option tells Rails to use the old
    "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
    the possible escalation vulnerability in place. Setting this option to true
    is not recommended, but can aid in upgrading.

    • config.active_record.yaml_column_permitted_classes

    The "safe YAML" loading method does not allow all classes to be deserialized
    by default. This option allows you to specify classes deemed "safe" in your
    application. For example, if your application uses Symbol and Time in
    serialized data, you can add Symbol and Time to the allowed list as follows:

    config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
    

    [CVE-2022-32224]

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by rafaelfranca over 3 years ago

https://github.com/rails/rails - 6.0.5.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Change ActiveRecord::Coders::YAMLColumn default to safe_load

    This adds two new configuration options The configuration options are as
    follows:

    • config.active_storage.use_yaml_unsafe_load

    When set to true, this configuration option tells Rails to use the old
    "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
    the possible escalation vulnerability in place. Setting this option to true
    is not recommended, but can aid in upgrading.

    • config.active_record.yaml_column_permitted_classes

    The "safe YAML" loading method does not allow all classes to be deserialized
    by default. This option allows you to specify classes deemed "safe" in your
    application. For example, if your application uses Symbol and Time in
    serialized data, you can add Symbol and Time to the allowed list as follows:

    config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
    

    [CVE-2022-32224]

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by rafaelfranca over 3 years ago

https://github.com/rails/rails - 5.2.8.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Change ActiveRecord::Coders::YAMLColumn default to safe_load

    This adds two new configuration options The configuration options are as
    follows:

    • config.active_storage.use_yaml_unsafe_load

    When set to true, this configuration option tells Rails to use the old
    "unsafe" YAML loading strategy, maintaining the existing behavior but leaving
    the possible escalation vulnerability in place. Setting this option to true
    is not recommended, but can aid in upgrading.

    • config.active_record.yaml_column_permitted_classes

    The "safe YAML" loading method does not allow all classes to be deserialized
    by default. This option allows you to specify classes deemed "safe" in your
    application. For example, if your application uses Symbol and Time in
    serialized data, you can add Symbol and Time to the allowed list as follows:

    config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
    

    [CVE-2022-32224]

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca over 3 years ago

https://github.com/rails/rails -

Active Support

  • Redis cache store is now compatible with redis-rb 5.0.

    Jean Boussier

  • Fix NoMethodError on custom ActiveSupport::Deprecation behavior.

    ActiveSupport::Deprecation.behavior= was supposed to accept any object
    that responds to call, but in fact its internal implementation assumed that
    this object could respond to arity, so it was restricted to only Proc objects.

    This change removes this arity restriction of custom behaviors.

    Ryo Nakamura

Active Model

  • Handle name clashes in attribute methods code generation cache.

    When two distinct attribute methods would generate similar names,
    the first implementation would be incorrectly re-used.

    class A
      attribute_method_suffix "_changed?"
      define_attribute_methods :x
    end
    
    class B
      attribute_method_suffix "?"
      define_attribute_methods :x_changed
    end
    

    Jean Boussier

Active Record

  • Symbol is allowed by default for YAML columns

    Étienne Barrié

  • Fix ActiveRecord::Store to serialize as a regular Hash

    Previously it would serialize as an ActiveSupport::HashWithIndifferentAccess
    which is wasteful and cause problem with YAML safe_load.

    Jean Boussier

  • Add timestamptz as a time zone aware type for PostgreSQL

    This is required for correctly parsing timestamp with time zone values in your database.

    If you don't want this, you can opt out by adding this initializer:

    ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
    

    Alex Ghiculescu

  • Fix supporting timezone awareness for tsrange and tstzrange array columns.

    # In database migrations
    add_column :shops, :open_hours, :tsrange, array: true
    # In app config
    ActiveRecord::Base.time_zone_aware_types += [:tsrange]
    # In the code times are properly converted to app time zone
    Shop.create!(open_hours: [Time.current..8.hour.from_now])
    

    Wojciech Wnętrzak

  • Resolve issue where a relation cache_version could be left stale.

    Previously, when reset was called on a relation object it did not reset the cache_versions
    ivar. This led to a confusing situation where despite having the correct data the relation
    still reported a stale cache_version.

    Usage:

    developers = Developer.all
    developers.cache_version
    
    Developer.update_all(updated_at: Time.now.utc + 1.second)
    
    developers.cache_version # Stale cache_version
    developers.reset
    developers.cache_version # Returns the current correct cache_version
    

    Fixes #45341.

    Austen Madden

  • Fix load_async when called on an association proxy.

    Calling load_async directly an association would schedule
    a query but never use it.

    comments = post.comments.load_async # schedule a query
    comments.to_a # perform an entirely new sync query
    

    Now it does use the async query, however note that it doesn't
    cause the association to be loaded.

    Jean Boussier

  • Fix eager loading for models without primary keys.

    Anmol Chopra, Matt Lawrence, and Jonathan Hefner

  • rails db:schema:{dump,load} now checks ENV["SCHEMA_FORMAT"] before config

    Since rails db:structure:{dump,load} was deprecated there wasn't a simple
    way to dump a schema to both SQL and Ruby formats. You can now do this with
    an environment variable. For example:

    SCHEMA_FORMAT=sql rake db:schema:dump
    

    Alex Ghiculescu

  • Fix Hstore deserialize regression.

    edsharp

Action View

  • Guard against ActionView::Helpers::FormTagHelper#field_name calls with nil
    object_name arguments. For example:

    <%= fields do |f| %>
      <%= f.field_name :body %>
    <% end %>
    

    Sean Doyle

  • Strings returned from strip_tags are correctly tagged html_safe?

    Because these strings contain no HTML elements and the basic entities are escaped, they are safe
    to be included as-is as PCDATA in HTML content. Tagging them as html-safe avoids double-escaping
    entities when being concatenated to a SafeBuffer during rendering.

    Fixes rails/rails-html-sanitizer#124

    Mike Dalessio

Action Pack

  • Prevent ActionDispatch::ServerTiming from overwriting existing values in Server-Timing.

    Previously, if another middleware down the chain set Server-Timing header,
    it would overwritten by ActionDispatch::ServerTiming.

    Jakub Malinowski

Active Job

  • Update ActiveJob::QueueAdapters::QueAdapter to remove deprecation warning.

    Remove a deprecation warning introduced in que 1.2 to prepare for changes in
    que 2.0 necessary for Ruby 3 compatibility.

    Damir Zekic and Adis Hasovic

Action Mailer

  • No changes.

Action Cable

  • The Redis adapter is now compatible with redis-rb 5.0

    Compatibility with redis-rb 3.x was dropped.

    Jean Boussier

  • The Action Cable server is now mounted with anchor: true.

    This means that routes that also start with /cable will no longer clash with Action Cable.

    Alex Ghiculescu

Active Storage

  • Fixes proxy downloads of files over 5MiB

    Previously, trying to view and/or download files larger than 5mb stored in
    services like S3 via proxy mode could return corrupted files at around
    5.2mb or cause random halts in the download. Now,
    ActiveStorage::Blobs::ProxyController correctly handles streaming these
    larger files from the service to the client without any issues.

    Fixes #44679

    Felipe Raul

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • config.allow_concurrency = false now use a Monitor instead of a Mutex

    This allows to enable config.active_support.executor_around_test_case even
    when config.allow_concurrency is disabled.

    Jean Boussier

  • Skip Active Storage and Action Mailer if Active Job is skipped.

    Étienne Barrié

  • Correctly check if frameworks are disabled when running app:update.

    Étienne Barrié and Paulo Barros

  • Fixed config.active_support.cache_format_version never being applied.

    Rails 7.0 shipped with a new serializer for Rails.cache, but the associated config
    wasn't working properly. Note that even after this fix, it can only be applied from
    the application.rb file.

    Alex Ghiculescu

- Ruby
Published by jhawthorn over 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.1.7

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Symbol is allowed by default for YAML columns

    Étienne Barrié

  • Fix ActiveRecord::Store to serialize as a regular Hash

    Previously it would serialize as an ActiveSupport::HashWithIndifferentAccess
    which is wasteful and cause problem with YAML safe_load.

    Jean Boussier

  • Fix PG.connect keyword arguments deprecation warning on ruby 2.7

    Fixes #44307.

    Nikita Vasilevsky

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Respect Active Record's primary_key_type in Active Storage migrations. Backported from 7.0.

    fatkodima

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by jhawthorn over 3 years ago

https://github.com/rails/rails - https://github.com/rails/rails/releases/tag/v6.0.6

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Symbol is allowed by default for YAML columns

    Étienne Barrié

Action View

  • No changes.

Action Pack

  • No changes.

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.

- Ruby
Published by jhawthorn over 3 years ago

https://github.com/rails/rails - 7.0.3

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • Some internal housekeeping on reloads could break custom respond_to?
    methods in class objects that referenced reloadable constants. See
    #44125 for details.

    Xavier Noria

  • Fixed MariaDB default function support.

    Defaults would be written wrong in "db/schema.rb" and not work correctly
    if using db:schema:load. Further more the function name would be
    added as string content when saving new records.

    kaspernj

  • Fix remove_foreign_key with :if_exists option when foreign key actually exists.

    fatkodima

  • Remove --no-comments flag in structure dumps for PostgreSQL

    This broke some apps that used custom schema comments. If you don't want
    comments in your structure dump, you can use:

    ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
    

    Alex Ghiculescu

  • Use the model name as a prefix when filtering encrypted attributes from logs.

    For example, when encrypting Person#name it will add person.name as a filter
    parameter, instead of just name. This prevents unintended filtering of parameters
    with a matching name in other models.

    Jorge Manrubia

  • Fix quoting of ActiveSupport::Duration and Rational numbers in the MySQL adapter.

    Kevin McPhillips

  • Fix change_column_comment to preserve column's AUTO_INCREMENT in the MySQL adapter

    fatkodima

Action View

  • Ensure models passed to form_for attempt to call to_model.

    Sean Doyle

Action Pack

  • Allow relative redirects when raise_on_open_redirects is enabled.

    Tom Hughes

  • Fix authenticate_with_http_basic to allow for missing password.

    Before Rails 7.0 it was possible to handle basic authentication with only a username.

    authenticate_with_http_basic do |token, _|
      ApiClient.authenticate(token)
    end
    

    This ability is restored.

    Jean Boussier

  • Fix content_security_policy returning invalid directives.

    Directives such as self, unsafe-eval and few others were not
    single quoted when the directive was the result of calling a lambda
    returning an array.

    content_security_policy do |policy|
      policy.frame_ancestors lambda { [:self, "https://example.com"] }
    end
    

    With this fix the policy generated from above will now be valid.

    Edouard Chin

  • Fix skip_forgery_protection to run without raising an error if forgery
    protection has not been enabled / verify_authenticity_token is not a
    defined callback.

    This fix prevents the Rails 7.0 Welcome Page (/) from raising an
    ArgumentError if default_protect_from_forgery is false.

    Brad Trick

  • Fix ActionController::Live to copy the IsolatedExecutionState in the ephemeral thread.

    Since its inception ActionController::Live has been copying thread local variables
    to keep things such as CurrentAttributes set from middlewares working in the controller action.

    With the introduction of IsolatedExecutionState in 7.0, some of that global state was lost in
    ActionController::Live controllers.

    Jean Boussier

  • Fix setting trailing_slash: true in route definition.

    get '/test' => "test#index", as: :test, trailing_slash: true
    
    test_path() # => "/test/"
    

    Jean Boussier

Active Job

  • Add missing bigdecimal require in ActiveJob::Arguments

    Could cause uninitialized constant ActiveJob::Arguments::BigDecimal (NameError)
    when loading Active Job in isolation.

    Jean Boussier

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Don't stream responses in redirect mode

    Previously, both redirect mode and proxy mode streamed their
    responses which caused a new thread to be created, and could end
    up leaking connections in the connection pool. But since redirect
    mode doesn't actually send any data, it doesn't need to be
    streamed.

    Luke Lau

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • If reloading and eager loading are both enabled, after a reload Rails eager loads again the application code.

    Xavier Noria

  • Use controller_class_path in Rails::Generators::NamedBase#route_url

    The route_url method now returns the correct path when generating
    a namespaced controller with a top-level model using --model-name.

    Previously, when running this command:

    bin/rails generate scaffold_controller Admin/Post --model-name Post
    

    the comments above the controller action would look like:

    # GET /posts
    def index
      @posts = Post.all
    end
    

    afterwards, they now look like this:

    # GET /admin/posts
    def index
      @posts = Post.all
    end
    

    Fixes #44662.

    Andrew White

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.6

Active Support

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Escape dangerous characters in names of tags and names of attributes in the
    tag helpers, following the XML specification. Rename the option
    :escape_attributes to :escape, to simplify by applying the option to the
    whole tag.

    Álvaro Martín Fraguas

Action Pack

  • Allow Content Security Policy DSL to generate for API responses.

    Tim Wade

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.0.5

Active Support

  • Fix tag helper regression.

    Eileen Uchitelle

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

Action Text

  • Disentangle Action Text from ApplicationController

    Allow Action Text to be used without having an ApplicationController
    defined.
    This makes sure:

    • Action Text attachments render the correct URL host in mailers.
    • an ActionController::Renderer isn't allocated per request.
    • Sidekiq doesn't hang with the "classic" autoloader.

    Jonathan Hefner

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 5.2.8

Active Support

  • Fix tag helper regression.

    Eileen Uchitelle

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails -

Active Support

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Escape dangerous characters in names of tags and names of attributes in the
    tag helpers, following the XML specification. Rename the option
    :escape_attributes to :escape, to simplify by applying the option to the
    whole tag.

    Álvaro Martín Fraguas

Action Pack

  • Allow Content Security Policy DSL to generate for API responses.

    Tim Wade

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.5.1

Active Support

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Escape dangerous characters in names of tags and names of attributes in the
    tag helpers, following the XML specification. Rename the option
    :escape_attributes to :escape, to simplify by applying the option to the
    whole tag.

    Álvaro Martín Fraguas

Action Pack

  • Allow Content Security Policy DSL to generate for API responses.

    Tim Wade

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.0.4.8

Active Support

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Escape dangerous characters in names of tags and names of attributes in the
    tag helpers, following the XML specification. Rename the option
    :escape_attributes to :escape, to simplify by applying the option to the
    whole tag.

    Álvaro Martín Fraguas

Action Pack

  • Allow Content Security Policy DSL to generate for API responses.

    Tim Wade

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 5.2.7.1

Active Support

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Add the method ERB::Util.xml_name_escape to escape dangerous characters
    in names of tags and names of attributes, following the specification of XML.

    Álvaro Martín Fraguas

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • Fix and add protections for XSS in ActionView::Helpers and ERB::Util.

    Escape dangerous characters in names of tags and names of attributes in the
    tag helpers, following the XML specification. Rename the option
    :escape_attributes to :escape, to simplify by applying the option to the
    whole tag.

    Álvaro Martín Fraguas

Action Pack

  • Allow Content Security Policy DSL to generate for API responses.

    Tim Wade

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 5.2.7

Active Support

  • Restore support to Ruby 2.2.

    ojab

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Fix ActiveStorage.supported_image_processing_methods and
    ActiveStorage.unsupported_image_processing_arguments that were not being applied.

    Rafael Mendonça França

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.5

Active Support

  • Fix ActiveSupport::Duration.build to support negative values.

    The algorithm to collect the parts of the ActiveSupport::Duration
    ignored the sign of the value and accumulated incorrect part values. This
    impacted ActiveSupport::Duration#sum (which is dependent on parts) but
    not ActiveSupport::Duration#eql? (which is dependent on value).

    Caleb Buxton, Braden Staudacher

  • Time#change and methods that call it (eg. Time#advance) will now
    return a Time with the timezone argument provided, if the caller was
    initialized with a timezone argument.

    Fixes #42467.

    Alex Ghiculescu

  • Clone to keep extended Logger methods for tagged logger.

    Orhan Toy

  • assert_changes works on including ActiveSupport::Assertions module.

    Pedro Medeiros

Active Model

  • Clear secure password cache if password is set to nil

    Before:

    user.password = 'something'
    user.password = nil

    user.password # => 'something'

    Now:

    user.password = 'something'
    user.password = nil

    user.password # => nil

    Markus Doits

  • Fix delegation in ActiveModel::Type::Registry#lookup and ActiveModel::Type.lookup

    Passing a last positional argument {} would be incorrectly considered as keyword argument.

    Benoit Daloze

  • Fix to_json after changes_applied for ActiveModel::Dirty object.

    Ryuta Kamizono

Active Record

  • Fix ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate for Ruby 2.6.

    Ruby 2.6 and 2.7 have slightly different implementations of the String#@- method.
    In Ruby 2.6, the receiver of the String#@- method is modified under certain circumstances.
    This was later identified as a bug (https://bugs.ruby-lang.org/issues/15926) and only
    fixed in Ruby 2.7.

    Before the changes in this commit, the
    ActiveRecord::ConnectionAdapters::SchemaCache#deep_deduplicate method, which internally
    calls the String#@- method, could also modify an input string argument in Ruby 2.6 --
    changing a tainted, unfrozen string into a tainted, frozen string.

    Fixes #43056

    Eric O'Hanlon

  • Fix migration compatibility to create SQLite references/belongs_to column as integer when
    migration version is 6.0.

    reference/belongs_to in migrations with version 6.0 were creating columns as
    bigint instead of integer for the SQLite Adapter.

    Marcelo Lauxen

  • Fix dbconsole for 3-tier config.

    Eileen M. Uchitelle

  • Better handle SQL queries with invalid encoding.

    Post.create(name: "broken \xC8 UTF-8")
    

    Would cause all adapters to fail in a non controlled way in the code
    responsible to detect write queries.

    The query is now properly passed to the database connection, which might or might
    not be able to handle it, but will either succeed or failed in a more correct way.

    Jean Boussier

  • Ignore persisted in-memory records when merging target lists.

    Kevin Sjöberg

  • Fix regression bug that caused ignoring additional conditions for preloading
    has_many through relations.

    Fixes #43132

    Alexander Pauly

  • Fix ActiveRecord::InternalMetadata to not be broken by
    config.active_record.record_timestamps = false

    Since the model always create the timestamp columns, it has to set them, otherwise it breaks
    various DB management tasks.

    Fixes #42983

    Jean Boussier

  • Fix duplicate active record objects on inverse_of.

    Justin Carvalho

  • Fix duplicate objects stored in has many association after save.

    Fixes #42549.

    Alex Ghiculescu

  • Fix performance regression in CollectionAssocation#build.

    Alex Ghiculescu

  • Fix retrieving default value for text column for MariaDB.

    fatkodima

Action View

  • preload_link_tag properly inserts as attributes for files with image MIME
    types, such as JPG or SVG.

    Nate Berkopec

  • Add autocomplete="off" to all generated hidden fields.

    Fixes #42610.

    Ryan Baumann

  • Fix current_page? when URL has trailing slash.

    This fixes the current_page? helper when the given URL has a trailing slash,
    and is an absolute URL or also has query params.

    Fixes #33956.

    Jonathan Hefner

Action Pack

  • Fix content_security_policy returning invalid directives.

    Directives such as self, unsafe-eval and few others were not
    single quoted when the directive was the result of calling a lambda
    returning an array.

    content_security_policy do |policy|
      policy.frame_ancestors lambda { [:self, "https://example.com"] }
    end
    

    With this fix the policy generated from above will now be valid.

    Edouard Chin

  • Update HostAuthorization middleware to render debug info only
    when config.consider_all_requests_local is set to true.

    Also, blocked host info is always logged with level error.

    Fixes #42813.

    Nikita Vyrko

  • Dup arrays that get "converted".

    Fixes #43681.

    Aaron Patterson

  • Don't show deprecation warning for equal paths.

    Anton Rieder

  • Fix crash in ActionController::Instrumentation with invalid HTTP formats.

    Fixes #43094.

    Alex Ghiculescu

  • Add fallback host for SystemTestCase driven by RackTest.

    Fixes #42780.

    Petrik de Heus

  • Add more detail about what hosts are allowed.

    Alex Ghiculescu

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • The Action Cable client now ensures successful channel subscriptions:

    • The client maintains a set of pending subscriptions until either
      the server confirms the subscription or the channel is torn down.
    • Rectifies the race condition where an unsubscribe is rapidly followed
      by a subscribe (on the same channel identifier) and the requests are
      handled out of order by the ActionCable server, thereby ignoring the
      subscribe command.

    Daniel Spinosa

  • Truncate broadcast logging messages.

    J Smith

Active Storage

  • Attachments can be deleted after their association is no longer defined.

    Fixes #42514

    Don Sisco

Action Mailbox

  • Add attachments to the list of permitted parameters for inbound emails conductor.

    When using the conductor to test inbound emails with attachments, this prevents an
    unpermitted parameter warning in default configurations, and prevents errors for
    applications that set:

    config.action_controller.action_on_unpermitted_parameters = :raise
    

    David Jones, Dana Henke

Action Text

  • Fix Action Text extra trix content wrapper.

    Alexandre Ruban

Railties

  • In zeitwerk mode, setup the once autoloader first, and the main autoloader after it.
    This order plays better with shared namespaces.

    Xavier Noria

  • Handle paths with spaces when editing credentials.

    Alex Ghiculescu

  • Support Psych 4 when loading secrets.

    Nat Morcos

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 7.0.2.3

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Added image transformation validation via configurable allow-list.

    Variant now offers a configurable allow-list for
    transformation methods in addition to a configurable deny-list for arguments.

    [CVE-2022-21831]

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.4.7

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Added image transformation validation via configurable allow-list.

    Variant now offers a configurable allow-list for
    transformation methods in addition to a configurable deny-list for arguments.

    [CVE-2022-21831]

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.0.4.7

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Added image transformation validation via configurable allow-list.

    Variant now offers a configurable allow-list for
    transformation methods in addition to a configurable deny-list for arguments.

    [CVE-2022-21831]

Action Mailbox

  • No changes.

Action Text

  • No changes.

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 5.2.6.3

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • No changes.

Active Job

  • No changes.

Action Mailer

  • No changes.

Action Cable

  • No changes.

Active Storage

  • Added image transformation validation via configurable allow-list.

    Variant now offers a configurable allow-list for
    transformation methods in addition to a configurable deny-list for arguments.

    [CVE-2022-21831]

Railties

  • No changes.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 7.0.2.2

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix Reloader method signature to work with the new Executor signature

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 7.0.2.1

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Under certain circumstances, the middleware isn't informed that the
    response body has been fully closed which result in request state not
    being fully reset before the next request

    [CVE-2022-23633]

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.4.6

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix Reloader method signature to work with the new Executor signature

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.1.4.5

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Under certain circumstances, the middleware isn't informed that the
    response body has been fully closed which result in request state not
    being fully reset before the next request

    [CVE-2022-23633]

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.0.4.6

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Fix Reloader method signature to work with the new Executor signature

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.

- Ruby
Published by rafaelfranca almost 4 years ago

https://github.com/rails/rails - 6.0.4.5

Active Support

  • No changes.

Active Model

  • No changes.

Active Record

  • No changes.

Action View

  • No changes.

Action Pack

  • Under certain circumstances, the middleware isn't informed that the
    response body has been fully closed which result in request state not
    being fully reset before the next request

    [CVE-2022-23633]

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.

- Ruby
Published by rafaelfranca almost 4 years ago