[!WARNING]
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Release Notes
rails/rails (rails)
### [`v8.0.0`](https://redirect.github.com/rails/rails/releases/tag/v8.0.0): 8.0.0
[Compare Source](https://redirect.github.com/rails/rails/compare/v7.2.2...v8.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:
```ruby
{ 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
```
After this change:
```ruby
{ 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:
```ruby
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_path`s 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.
```ruby
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`.
```ruby
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.
```ruby
```
### 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:
```ruby
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](https://redirect.github.com/rails/rails/issues/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.
```ruby
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](https://redirect.github.com/rails/rails/issues/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.
```ruby
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](https://redirect.github.com/rails/rails/issues/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](https://redirect.github.com/rails/rails/issues/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.
```ruby
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.
```ruby
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:
```ruby
enable_extension "heroku_ext.pgcrypto"
enable_extension "pg_stat_statements"
```
then the generated schema dump will also contain:
```ruby
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.
```ruby
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.
```ruby
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`.
```ruby
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.
```ruby
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:
```ruby
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.
```ruby
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.
```erb
<%= 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`
```ruby
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.
```ruby
```
### 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.
```ruby
### 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.
```ruby
```
### 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
```ruby
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`
```ruby
```
### 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.
```ruby
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 `1`s 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](https://redirect.github.com/rails/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](https://redirect.github.com/rails/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](https://redirect.github.com/rails/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)`:
```ruby
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:
```ruby
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](https://guides.rubyonrails.org/v7.2/classic_to_zeitwerk_howto.html),
in case you need it.
*Petrik de Heus*
Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
[ ] If you want to rebase/retry this PR, check this box
This PR contains the following updates:
'~> 7.2.0'
->'~> 8.0.0'
Release Notes
rails/rails (rails)
### [`v8.0.0`](https://redirect.github.com/rails/rails/releases/tag/v8.0.0): 8.0.0 [Compare Source](https://redirect.github.com/rails/rails/compare/v7.2.2...v8.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: ```ruby { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2 ``` After this change: ```ruby { 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: ```ruby 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_path`s 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. ```ruby 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`. ```ruby 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. ```ruby ``` ### 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: ```ruby 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](https://redirect.github.com/rails/rails/issues/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. ```ruby 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](https://redirect.github.com/rails/rails/issues/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. ```ruby 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](https://redirect.github.com/rails/rails/issues/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](https://redirect.github.com/rails/rails/issues/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. ```ruby 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. ```ruby 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: ```ruby enable_extension "heroku_ext.pgcrypto" enable_extension "pg_stat_statements" ``` then the generated schema dump will also contain: ```ruby 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. ```ruby 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. ```ruby 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`. ```ruby 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. ```ruby 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: ```ruby 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. ```ruby 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. ```erb <%= 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` ```ruby 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. ```ruby ``` ### 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. ```ruby ### 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. ```ruby ``` ### 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 ```ruby 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` ```ruby ``` ### 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. ```ruby 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 `1`s 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](https://redirect.github.com/rails/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](https://redirect.github.com/rails/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](https://redirect.github.com/rails/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)`: ```ruby 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: ```ruby 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](https://guides.rubyonrails.org/v7.2/classic_to_zeitwerk_howto.html), in case you need it. *Petrik de Heus*Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.