* Add `update_attribute!` to `ActiveRecord::Persistence` Similar to `update_attribute`, but raises `ActiveRecord::RecordNotSaved` when a `before_*` callback throws `:abort`. ```ruby class Topic < ActiveRecord::Base before_save :check_title def check_title throw(:abort) if title == "abort" end end topic = Topic.create(title: "Test Title") # #=> # topic.update_attribute!(:title, "Another Title") # #=> # topic.update_attribute!(:title, "abort") # raises ActiveRecord::RecordNotSaved ``` *Drew Tempelmeyer* * Avoid loading every record in `ActiveRecord::Relation#pretty_print` ```ruby # Before pp Foo.all # Loads the whole table. # After pp Foo.all # Shows 10 items and an ellipsis. ``` *Ulysse Buonomo* * Change `QueryMethods#in_order_of` to drop records not listed in values. `in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version. *Kevin Newton* * Allow named expression indexes to be revertible. Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal. ```ruby add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property) ``` Fixes #43331. *Oliver Günther* * Fix incorrect argument in PostgreSQL structure dump tasks. Updating the `--no-comment` argument added in Rails 7 to the correct `--no-comments` argument. *Alex Dent* * Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0. Reference/belongs_to in migrations with version 6.0 were creating columns as bigint instead of integer for the SQLite Adapter. *Marcelo Lauxen* * Add a deprecation warning when `prepared_statements` configuration is not set for the mysql2 adapter. *Thiago Araujo and Stefanni Brasil* * Fix `QueryMethods#in_order_of` to handle empty order list. ```ruby Post.in_order_of(:id, []).to_a ``` Also more explicitly set the column as secondary order, so that any other value is still ordered. *Jean Boussier* * Fix quoting of column aliases generated by calculation methods. Since the alias is derived from the table name, we can't assume the result is a valid identifier. ```ruby class Test < ActiveRecord::Base self.table_name = '1abc' end Test.group(:id).count # syntax error at or near "1" (ActiveRecord::StatementInvalid) # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1... ``` *Jean Boussier* * Add `authenticate_by` when using `has_secure_password`. `authenticate_by` is intended to replace code like the following, which returns early when a user with a matching email is not found: ```ruby User.find_by(email: "...")&.authenticate("...") ``` Such code is vulnerable to timing-based enumeration attacks, wherein an attacker can determine if a user account with a given email exists. After confirming that an account exists, the attacker can try passwords associated with that email address from other leaked databases, in case the user re-used a password across multiple sites (a common practice). Additionally, knowing an account email address allows the attacker to attempt a targeted phishing ("spear phishing") attack. `authenticate_by` addresses the vulnerability by taking the same amount of time regardless of whether a user with a matching email is found: ```ruby User.authenticate_by(email: "...", password: "...") ``` *Jonathan Hefner* Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activerecord/CHANGELOG.md) for previous changes.