Ruby on Rails: v7.0.0.rc1 Release

Release date:
December 6, 2021
Previous version:
v7.0.0.alpha2 (released September 15, 2021)
Magnitude:
25,016 Diff Delta
Contributors:
151 total committers
Data confidence:
Commits:

275 Features Released with v7.0.0.rc1

Top Contributors in v7.0.0.rc1

rafaelfranca
byroot
esparta
fxn
composerinteralia
seanpdoyle
eileencodes
ghiculescu
DmitryTsepelev
ryanfb

Directory Browser for v7.0.0.rc1

We haven't yet finished calculating and confirming the files and directories changed in this release. Please check back soon.

Release Notes Published

Active Support

  • Deprecate passing a format to #to_s in favor of #to_formatted_s in Array, Range, Date, DateTime, Time, BigDecimal, Float and, Integer.

    Rafael Mendonça França

  • Document ActiveSupport::Testing::Deprecation.

    Sam Bostock & Sam Jordan

  • Add Pathname#existence.

    Pathname.new("file").existence&.read
    

    Timo Schilling

  • Remove deprecate ActiveSupport::Multibyte::Unicode.default_normalization_form.

    Rafael Mendonça França

  • Remove deprecated support to use Range#include? to check the inclusion of a value in a date time range is deprecated.

    Rafael Mendonça França

  • Remove deprecated URI.parser.

    Rafael Mendonça França

  • Remove deprecated config.active_support.use_sha1_digests.

    Rafael Mendonça França

  • Invoking Object#with_options without a &block argument returns the ActiveSupport::OptionMerger instance.

    Sean Doyle

  • Rails.application.executor hooks can now be called around every test

    This helps to better simulate request or job local state being reset around tests and prevents state leaking from one test to another.

    However it requires the executor hooks executed in the test environment to be re-entrant.

    To enable this, set config.active_support.executor_around_test_case = true (this is the default in Rails 7).

    Jean Boussier

  • ActiveSupport::DescendantsTracker now mostly delegate to Class#descendants on Ruby 3.1

    Ruby now provides a fast Class#descendants making ActiveSupport::DescendantsTracker mostly useless.

    As a result the following methods are deprecated:

    • ActiveSupport::DescendantsTracker.direct_descendants
    • ActiveSupport::DescendantsTracker#direct_descendants

    Jean Boussier

  • Fix the Digest::UUID.uuid_from_hash behavior for namespace IDs that are different from the ones defined on Digest::UUID.

    The new behavior will be enabled by setting the config.active_support.use_rfc4122_namespaced_uuids option to true and is the default for new apps.

    The old behavior is the default for upgraded apps and will output a deprecation warning every time a value that is different than one of the constants defined on the Digest::UUID extension is used as the namespace ID.

    Alex Robbin, Erich Soares Machado, Eugene Kenny

  • ActiveSupport::Inflector::Inflections#clear(:acronyms) is now supported, and inflector.clear / inflector.clear(:all) also clears acronyms.

    Alex Ghiculescu, Oliver Peate

Active Model

  • Remove support to Marshal load Rails 5.x ActiveModel::AttributeSet format.

    Rafael Mendonça França

  • Remove support to Marshal and YAML load Rails 5.x error format.

    Rafael Mendonça França

  • Remove deprecated support to use []= in ActiveModel::Errors#messages.

    Rafael Mendonça França

  • Remove deprecated support to delete errors from ActiveModel::Errors#messages.

    Rafael Mendonça França

  • Remove deprecated support to clear errors from ActiveModel::Errors#messages.

    Rafael Mendonça França

  • Remove deprecated support concat errors to ActiveModel::Errors#messages.

    Rafael Mendonça França

  • Remove deprecated ActiveModel::Errors#to_xml.

    Rafael Mendonça França

  • Remove deprecated ActiveModel::Errors#keys.

    Rafael Mendonça França

  • Remove deprecated ActiveModel::Errors#values.

    Rafael Mendonça França

  • Remove deprecated ActiveModel::Errors#slice!.

    Rafael Mendonça França

  • Remove deprecated ActiveModel::Errors#to_h.

    Rafael Mendonça França

  • Remove deprecated enumeration of ActiveModel::Errors instances as a Hash.

    Rafael Mendonça França

  • 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

Active Record

  • Remove deprecated ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Connection#in_clause_length.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Connection#allowed_index_name_length.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base#remove_connection.

    Rafael Mendonça França

  • Load STI Models in fixtures

    Data from Fixtures now loads based on the specific class for models with Single Table Inheritance. This affects enums defined in subclasses, previously the value of these fields was not parsed and remained nil

    Andres Howard

  • #authenticate returns false when the password is blank instead of raising an error.

    Muhammad Muhammad Ibrahim

  • Fix ActiveRecord::QueryMethods#in_order_of behavior for integer enums.

    ActiveRecord::QueryMethods#in_order_of didn't work as expected for enums stored as integers in the database when passing an array of strings or symbols as the order argument. This unexpected behavior occurred because the string or symbol values were not casted to match the integers in the database.

    The following example now works as expected:

    class Book < ApplicationRecord
      enum status: [:proposed, :written, :published]
    end
    
    Book.in_order_of(:status, %w[written published proposed])
    

    Alexandre Ruban

  • Ignore persisted in-memory records when merging target lists.

    Kevin Sjöberg

  • Add a new option :update_only to upsert_all to configure the list of columns to update in case of conflict.

    Before, you could only customize the update SQL sentence via :on_duplicate. There is now a new option :update_only that lets you provide a list of columns to update in case of conflict:

    Commodity.upsert_all(
      [
        { id: 2, name: "Copper", price: 4.84 },
        { id: 4, name: "Gold", price: 1380.87 },
        { id: 6, name: "Aluminium", price: 0.35 }
      ],
      update_only: [:price] # Only prices will be updated
    )
    

    Jorge Manrubia

  • Remove deprecated ActiveRecord::Result#map! and ActiveRecord::Result#collect!.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.configurations.to_h.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.configurations.default_hash.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.arel_attribute.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.connection_config.

    Rafael Mendonça França

  • Filter attributes in SQL logs

    Previously, SQL queries in logs containing ActiveRecord::Base.filter_attributes were not filtered.

    Now, the filter attributes will be masked [FILTERED] in the logs when prepared_statement is enabled.

    # Before:
      Foo Load (0.2ms)  SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ?  [["passw", "hello"], ["LIMIT", 1]]
    
    # After:
      Foo Load (0.5ms)  SELECT "foos".* FROM "foos" WHERE "foos"."passw" = ? LIMIT ?  [["passw", "[FILTERED]"], ["LIMIT", 1]]
    

    Aishwarya Subramanian

  • Remove deprecated Tasks::DatabaseTasks.spec.

    Rafael Mendonça França

  • Remove deprecated Tasks::DatabaseTasks.current_config.

    Rafael Mendonça França

  • Deprecate Tasks::DatabaseTasks.schema_file_type.

    Rafael Mendonça França

  • Remove deprecated Tasks::DatabaseTasks.dump_filename.

    Rafael Mendonça França

  • Remove deprecated Tasks::DatabaseTasks.schema_file.

    Rafael Mendonça França

  • Remove deprecated environment and name arguments from Tasks::DatabaseTasks.schema_up_to_date?.

    Rafael Mendonça França

  • Merging conditions on the same column no longer maintain both conditions, and will be consistently replaced by the latter condition.

    # Rails 6.1 (IN clause is replaced by merger side equality condition)
    Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
    # Rails 6.1 (both conflict conditions exists, deprecated)
    Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
    # Rails 6.1 with rewhere to migrate to Rails 7.0's behavior
    Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
    # Rails 7.0 (same behavior with IN clause, mergee side condition is consistently replaced)
    Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
    Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
    
    *Rafael Mendonça França*
    
  • Remove deprecated support to Model.reorder(nil).first to search using non-deterministic order.

    Rafael Mendonça França

  • Remove deprecated rake tasks:

    • db:schema:load_if_ruby
    • db:structure:dump
    • db:structure:load
    • db:structure:load_if_sql
    • db:structure:dump:#{name}
    • db:structure:load:#{name}
    • db:test:load_structure
    • db:test:load_structure:#{name}

    Rafael Mendonça França

  • Remove deprecated DatabaseConfig#config method.

    Rafael Mendonça França

  • Rollback transactions when the block returns earlier than expected.

    Before this change, when a transaction block returned early, the transaction would be committed.

    The problem is that timeouts triggered inside the transaction block was also making the incomplete transaction to be committed, so in order to avoid this mistake, the transaction block is rolled back.

    Rafael Mendonça França

  • Add middleware for automatic shard swapping.

    Provides a basic middleware to perform automatic shard swapping. Applications will provide a resolver which will determine for an individual request which shard should be used. Example:

    config.active_record.shard_resolver = ->(request) {
      subdomain = request.subdomain
      tenant = Tenant.find_by_subdomain!(subdomain)
      tenant.shard
    }
    

    See guides for more details.

    Eileen M. Uchitelle, John Crepezzi

  • Remove deprecated support to pass a column to type_cast.

    Rafael Mendonça França

  • Remove deprecated support to type cast to database values ActiveRecord::Base objects.

    Rafael Mendonça França

  • Remove deprecated support to quote ActiveRecord::Base objects.

    Rafael Mendonça França

  • Remove deprecacated support to resolve connection using "primary" as connection specification name.

    Rafael Mendonça França

  • Remove deprecation warning when using :interval column is used in PostgreSQL database.

    Now, interval columns will return ActiveSupport::Duration objects instead of strings.

    To keep the old behavior, you can add this line to your model:

    attribute :column, :string
    

    Rafael Mendonça França

  • Remove deprecated support to YAML load ActiveRecord::Base instance in the Rails 4.2 and 4.1 formats.

    Rafael Mendonça França

  • Remove deprecated option :spec_name in the configs_for method.

    Rafael Mendonça França

  • Remove deprecated ActiveRecord::Base.allow_unsafe_raw_sql.

    Rafael Mendonça França

  • Fix regression bug that caused ignoring additional conditions for preloading has_many-through relations.

    Fixes #43132

    Alexander Pauly

  • Fix has_many inversing recursion on models with recursive associations.

    Gannon McGibbon

  • Add accepts_nested_attributes_for support for delegated_type

    class Entry < ApplicationRecord
      delegated_type :entryable, types: %w[ Message Comment ]
      accepts_nested_attributes_for :entryable
    end
    
    entry = Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
    # => #<Entry:0x00>
    # id: 1
    # entryable_id: 1,
    # entryable_type: 'Message'
    # ...>
    
    entry.entryable
    # => #<Message:0x01>
    # id: 1
    # content: 'Hello world'
    # ...>
    

    Previously it would raise an error:

    Entry.create(entryable_type: 'Message', entryable_attributes: { content: 'Hello world' })
    # ArgumentError: Cannot build association `entryable'. Are you trying to build a polymorphic one-to-one association?
    

    Sjors Baltus

  • Use subquery for DELETE with GROUP_BY and HAVING clauses.

    Prior to this change, deletes with GROUP_BY and HAVING were returning an error.

    After this change, GROUP_BY and HAVING are valid clauses in DELETE queries, generating the following query:

    DELETE FROM "posts" WHERE "posts"."id" IN (
        SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."id" HAVING (count(comments.id) >= 2))
    )  [["flagged", "t"]]
    

    Ignacio Chiazzo Cardarello

  • Use subquery for UPDATE with GROUP_BY and HAVING clauses.

    Prior to this change, updates with GROUP_BY and HAVING were being ignored, generating a SQL like this:

    UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
        SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
    )  [["flagged", "t"]]
    

    After this change, GROUP_BY and HAVING clauses are used as a subquery in updates, like this:

    UPDATE "posts" SET "flagged" = ? WHERE "posts"."id" IN (
        SELECT "posts"."id" FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
        GROUP BY posts.id HAVING (count(comments.id) >= 2)
    )  [["flagged", "t"]]
    

    Ignacio Chiazzo Cardarello

  • Add support for setting the filename of the schema or structure dump in the database config.

    Applications may now set their the filename or path of the schema / structure dump file in their database configuration.

    production:
      primary:
        database: my_db
        schema_dump: my_schema_dump_filename.rb
      animals:
        database: animals_db
        schema_dump: false
    

    The filename set in schema_dump will be used by the application. If set to false the schema will not be dumped. The database tasks are responsible for adding the database directory to the filename. If a full path is provided, the Rails tasks will use that instead of ActiveRecord::DatabaseTasks.db_dir.

    Eileen M. Uchitelle, Ryan Kerr

  • Add ActiveRecord::Base.prohibit_shard_swapping to prevent attempts to change the shard within a block.

    John Crepezzi, Eileen M. Uchitelle

  • Filter unchanged attributes with default function from insert query when partial_inserts is disabled.

    Akshay Birajdar, Jacopo Beschi

  • Add support for FILTER clause (SQL:2003) to Arel.

    Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.

    Andrey Novikov

  • Automatically set timestamps on record creation during bulk insert/upsert

    Prior to this change, only updates during an upsert operation (e.g. upsert_all) would touch timestamps (updated_{at,on}). Now, record creations also touch timestamp columns ({created,updated}_{at,on}).

    This behaviour is controlled by the <model>.record_timestamps config, matching the behaviour of create, update, etc. It can also be overridden by using the record_timestamps: keyword argument.

    Note that this means upsert_all on models with record_timestamps = false will no longer touch updated_{at,on} automatically.

    Sam Bostock

  • Don't require role when passing shard to connected_to.

    connected_to can now be called with a shard only. Note that role is still inherited if connected_to calls are nested.

    Eileen M. Uchitelle

  • Add option to lazily load the schema cache on the connection.

    Previously, the only way to load the schema cache in Active Record was through the Railtie on boot. This option provides the ability to load the schema cache on the connection after it's been established. Loading the cache lazily on the connection can be beneficial for Rails applications that use multiple databases because it will load the cache at the time the connection is established. Currently Railties doesn't have access to the connections before boot.

    To use the cache, set config.active_record.lazily_load_schema_cache = true in your application configuration. In addition a schema_cache_path should be set in your database configuration if you don't want to use the default "db/schema_cache.yml" path.

    Eileen M. Uchitelle

  • Allow automatic inverse_of detection for associations with scopes.

    Automatic inverse_of detection now works for associations with scopes. For example, the comments association here now automatically detects inverse_of: :post, so we don't need to pass that option:

    class Post < ActiveRecord::Base
      has_many :comments, -> { visible }
    end
    
    class Comment < ActiveRecord::Base
      belongs_to :post
    end
    

    Note that the automatic detection still won't work if the inverse association has a scope. In this example a scope on the post association would still prevent Rails from finding the inverse for the comments association.

    This will be the default for new apps in Rails 7. To opt in:

    config.active_record.automatic_scope_inversing = true
    

    Daniel Colson, Chris Bloom

  • Accept optional transaction args to ActiveRecord::Locking::Pessimistic#with_lock

    #with_lock now accepts transaction options like requires_new:, isolation:, and joinable:

  • Adds support for deferrable foreign key constraints in PostgreSQL.

    By default, foreign key constraints in PostgreSQL are checked after each statement. This works for most use cases, but becomes a major limitation when creating related records before the parent record is inserted into the database. One example of this is looking up / creating a person via one or more unique alias.

    Person.transaction do
      alias = Alias
        .create_with(user_id: SecureRandom.uuid)
        .create_or_find_by(name: "DHH")
    
      person = Person
        .create_with(name: "David Heinemeier Hansson")
        .create_or_find_by(id: alias.user_id)
    end
    

    Using the default behavior, the transaction would fail when executing the first INSERT statement.

    By passing the :deferrable option to the add_foreign_key statement in migrations, it's possible to defer this check.

    add_foreign_key :aliases, :person, deferrable: true
    

    Passing deferrable: true doesn't change the default behavior, but allows manually deferring the check using SET CONSTRAINTS ALL DEFERRED within a transaction. This will cause the foreign keys 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_foreign_key :aliases, :person, deferrable: :deferred
    

    Benedikt Deicke

  • Allow configuring Postgres password through the socket URL.

    For example: ruby ActiveRecord::DatabaseConfigurations::UrlConfig.new( :production, :production, 'postgres:///?user=user&password=secret&dbname=app', {} ).configuration_hash

    will now return,

    { :user=>"user", :password=>"secret", :dbname=>"app", :adapter=>"postgresql" }
    

    Abeid Ahmed

  • PostgreSQL: support custom enum types

    In migrations, use create_enum to add a new enum type, and t.enum to add a column.

    def up
      create_enum :mood, ["happy", "sad"]
    
      change_table :cats do |t|
        t.enum :current_mood, enum_type: "mood", default: "happy", null: false
      end
    end
    

    Enums will be presented correctly in schema.rb. Note that this is only supported by the PostgreSQL adapter.

    Alex Ghiculescu

  • Avoid COMMENT statements in PostgreSQL structure dumps

    COMMENT statements are now omitted from the output of db:structure:dump when using PostgreSQL >= 11. This allows loading the dump without a pgsql superuser account.

    Fixes #36816, #43107.

    Janosch Müller

  • Add support for generated columns in PostgreSQL adapter

    Generated columns are supported since version 12.0 of PostgreSQL. This adds support of those to the PostgreSQL adapter.

    create_table :users do |t|
      t.string :name
      t.virtual :name_upcased, type: :string, as: 'upper(name)', stored: true
    end
    

    Michał Begejowicz

Action View

  • Support fields model: [@nested, @model] the same way as form_with model: [@nested, @model].

    Sean Doyle

  • Infer HTTP verb [method] from a model or Array with model as the first argument to button_to when combined with a block:

    button_to(Workshop.find(1)){ "Update" }
    #=> <form method="post" action="/workshops/1" class="button_to">
    #=>   <input type="hidden" name="_method" value="patch" autocomplete="off" />
    #=>   <button type="submit">Update</button>
    #=> </form>
    
    button_to([ Workshop.find(1), Session.find(1) ]) { "Update" }
    #=> <form method="post" action="/workshops/1/sessions/1" class="button_to">
    #=>   <input type="hidden" name="_method" value="patch" autocomplete="off" />
    #=>   <button type="submit">Update</button>
    #=> </form>
    

    Sean Doyle

  • Support passing a Symbol as the first argument to FormBuilder#button:

    form.button(:draft, value: true)
    # => <button name="post[draft]" value="true" type="submit">Create post</button>
    
    form.button(:draft, value: true) do
      content_tag(:strong, "Save as draft")
    end
    # =>  <button name="post[draft]" value="true" type="submit">
    #       <strong>Save as draft</strong>
    #     </button>
    

    Sean Doyle

  • Introduce the field_name view helper, along with the FormBuilder#field_name counterpart:

    form_for @post do |f|
      f.field_tag :tag, name: f.field_name(:tag, multiple: true)
      # => <input type="text" name="post[tag][]">
    end
    

    Sean Doyle

  • Execute the ActionView::Base.field_error_proc within the context of the ActionView::Base instance:

    config.action_view.field_error_proc = proc { |html| content_tag(:div, html, class: "field_with_errors") }
    

    Sean Doyle

  • Add support for button_to ..., authenticity_token: false

    button_to "Create", Post.new, authenticity_token: false
    # => <form class="button_to" method="post" action="/posts"><button type="submit">Create</button></form>
    
    button_to "Create", Post.new, authenticity_token: true
    # => <form class="button_to" method="post" action="/posts"><button type="submit">Create</button><input type="hidden" name="form_token" value="abc123..." autocomplete="off" /></form>
    
    button_to "Create", Post.new, authenticity_token: "secret"
    # => <form class="button_to" method="post" action="/posts"><button type="submit">Create</button><input type="hidden" name="form_token" value="secret" autocomplete="off" /></form>
    

    Sean Doyle

  • Support rendering <form> elements without [action] attributes by:

    • form_with url: false or form_with ..., html: { action: false }
    • form_for ..., url: false or form_for ..., html: { action: false }
    • form_tag false or form_tag ..., action: false
    • button_to "...", false or button_to(false) { ... }

    Sean Doyle

  • Add :day_format option to date_select

    date_select("article", "written_on", day_format: ->(day) { day.ordinalize })
    # generates day options like <option value="1">1st</option>\n<option value="2">2nd</option>...
    

    Shunichi Ikegami

  • Allow link_to helper to infer link name from Model#to_s when it is used with a single argument:

    link_to @profile
    #=> <a href="/profiles/1">Eileen</a>
    

    This assumes the model class implements a to_s method like this:

    class Profile < ApplicationRecord
      # ...
      def to_s
        name
      end
    end
    

    Previously you had to supply a second argument even if the Profile model implemented a #to_s method that called the name method.

    link_to @profile, @profile.name
    #=> <a href="/profiles/1">Eileen</a>
    

    Olivier Lacan

  • Support svg unpaired tags for tag helper.

    tag.svg { tag.use('href' => "#cool-icon") }
    # => <svg><use href="#cool-icon"></svg>
    

    Oleksii Vasyliev

Action Pack

  • Rails.application.executor hooks can now be called around every request in a ActionController::TestCase

    This helps to better simulate request or job local state being reset between requests and prevent state leaking from one request to another.

    To enable this, set config.active_support.executor_around_test_case = true (this is the default in Rails 7).

    Alex Ghiculescu

  • Consider onion services secure for cookies.

    Justin Tracey

  • Remove deprecated Rails.config.action_view.raise_on_missing_translations.

    Rafael Mendonça França

  • Remove deprecated support to passing a path to fixture_file_upload relative to fixture_path.

    Rafael Mendonça França

  • Remove deprecated ActionDispatch::SystemTestCase#host!.

    Rafael Mendonça França

  • Remove deprecated Rails.config.action_dispatch.hosts_response_app.

    Rafael Mendonça França

  • Remove deprecated ActionDispatch::Response.return_only_media_type_on_content_type.

    Rafael Mendonça França

  • Raise ActionController::Redirecting::UnsafeRedirectError for unsafe redirect_to redirects.

    This allows rescue_from to be used to add a default fallback route:

    rescue_from ActionController::Redirecting::UnsafeRedirectError do
      redirect_to root_url
    end
    

    Kasper Timm Hansen, Chris Oliver

  • Add url_from to verify a redirect location is internal.

    Takes the open redirect protection from redirect_to so users can wrap a param, and fall back to an alternate redirect URL when the param provided one is unsafe.

    def create
      redirect_to url_from(params[:redirect_url]) || root_url
    end
    

    dmcge, Kasper Timm Hansen

  • Allow Capybara driver name overrides in SystemTestCase::driven_by

    Allow users to prevent conflicts among drivers that use the same driver type (selenium, poltergeist, webkit, rack test).

    Fixes #42502

    Chris LaRose

  • Allow multiline to be passed in routes when using wildcard segments.

    Previously routes with newlines weren't detected when using wildcard segments, returning a No route matches error. After this change, routes with newlines are detected on wildcard segments. Example

      draw do
        get "/wildcard/*wildcard_segment", to: SimpleApp.new("foo#index"), as: :wildcard
      end
    
      # After the change, the path matches.
      assert_equal "/wildcard/a%0Anewline", url_helpers.wildcard_path(wildcard_segment: "a\nnewline")
    

    Fixes #39103

    Ignacio Chiazzo

  • Treat html suffix in controller translation.

    Rui Onodera, Gavin Miller

  • Allow permitting numeric params.

    Previously it was impossible to permit different fields on numeric parameters. After this change you can specify different fields for each numbered parameter. For example params like, ruby book: { authors_attributes: { '0': { name: "William Shakespeare", age_of_death: "52" }, '1': { name: "Unattributed Assistant" }, '2': "Not a hash", 'new_record': { name: "Some name" } } }

    Before you could permit name on each author with, permit book: { authors_attributes: [ :name ] }

    After this change you can permit different keys on each numbered element, permit book: { authors_attributes: { '1': [ :name ], '0': [ :name, :age_of_death ] } }

    Fixes #41625

    Adam Hess

  • 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

  • Add Server-Timing middleware

Server-Timing specification defines how the server can communicate to browsers performance metrics about the request it is responding to.

The ServerTiming middleware is enabled by default on development environment by default using the config.server_timing setting and set the relevant duration metrics in the Server-Timing header

The full specification for Server-Timing header can be found in: https://www.w3.org/TR/server-timing/#dfn-server-timing-header-field

Sebastian Sogamoso, Guillermo Iguaran

Active Job

  • Remove deprecated :return_false_on_aborted_enqueue option.

    Rafael Mendonça França

  • Deprecated Rails.config.active_job.skip_after_callbacks_if_terminated.

    Rafael Mendonça França

  • Removed deprecated behavior that was not halting after_enqueue/after_perform callbacks when a previous callback was halted with throw :abort.

    Rafael Mendonça França

  • Raise an SerializationError in Serializer::ModuleSerializer if the module name is not present.

    Veerpal Brar

Action Mailer

  • Remove deprecated ActionMailer::DeliveryJob and ActionMailer::Parameterized::DeliveryJob in favor of ActionMailer::MailDeliveryJob.

    Rafael Mendonça França

  • email_address_with_name returns just the address if name is blank.

    Thomas Hutterer

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

Active Storage

  • Add ActiveStorage::Blob.compose to concatenate multiple blobs.

    Gannon McGibbon

  • Setting custom metadata on blobs are now persisted to remote storage.

    joshuamsager

  • Support direct uploads to multiple services.

    Dmitry Tsepelev

  • Invalid default content types are deprecated

    Blobs created with content_type image/jpg, image/pjpeg, image/bmp, text/javascript will now produce a deprecation warning, since these are not valid content types.

    These content types will be removed from the defaults in Rails 7.1.

    You can set config.active_storage.silence_invalid_content_types_warning = true to dismiss the warning.

    Alex Ghiculescu

Action Mailbox

  • Removed deprecated environment variable MAILGUN_INGRESS_API_KEY.

    Rafael Mendonça França

  • Removed deprecated Rails.application.credentials.action_mailbox.mailgun_api_key.

    Rafael Mendonça França

Action Text

  • Fix an issue with how nested lists were displayed when converting to plain text

    Matt Swanson

  • Allow passing in a custom direct_upload_url or blob_url_template to rich_text_area_tag.

    Lucas Mansur

Railties

  • Remove deprecated config in dbconsole.

    Rafael Mendonça França

  • Change default X-XSS-Protection header to disable XSS auditor

    This header has been deprecated and the XSS auditor it triggered has been removed from all major modern browsers (in favour of Content Security Policy) that implemented this header to begin with (Firefox never did).

    OWASP suggests setting this header to '0' to disable the default behaviour on old browsers as it can introduce additional security issues.

    Added the new behaviour as a framework default from Rails 7.0.

    Christian Sutter

  • Scaffolds now use date_field, time_field and datetime_field instead of date_select, time_select and datetime_select; thus providing native date/time pickers.

    Martijn Lafeber

  • Fix a regression in which autoload paths were initialized too late.

    Xavier Noria