rc2以後の更新はありません。
🔗 Active Record CHANGELOG(v7.1.0.rc2)
🔗 rails db:drop now removes -shm and -wal sqlite files by codergeek121 · Pull Request #49436 · rails/rails
rails db:drop
実行時にSQLite3のshmファイルや-walファイルも削除するようになった。Niklas Häusele
同CHANGELOGより
🔗 Revert "Merge pull request #49056 from joshuay03/raise-on-duplicate-a… · rails/rails@0ba14eb
同一クラス内で、ある関連付けに対する
#accepts_nested_attributes_for
が2回以上宣言された場合にArgumentError
を発生する変更(#49056)を取り消し。ここで取り消された振る舞いは、
#accepts_nested_attributes_for
内で定義したconcernが、そのconcernをinclude
しているクラス内でオーバーライドされる場合に壊れる。Rafael Mendonça França
同CHANGELOGより
🔗 Active Record CHANGELOG(v7.1.0.rc1)
🔗 Rename back unique keys to unique constraints by kamipo · Pull Request #49383 · rails/rails
(PostgreSQL)unique制約のネーミングを改善。
*_unique_key
という命名だと、uniqueインデックスの短縮形と誤解される。
*_unique_constraint
という命名なら誤解されない。Rails 7.1.0.beta1以前:
add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position" remove_unique_key :sections, name: "unique_section_position"
変更後:
add_unique_constraint :sections, [:position], deferrable: :deferred, name: "unique_section_position" remove_unique_constraint :sections, name: "unique_section_position"
Ryuta Kamizono
同CHANGELOGより
🔗 Fix duplicate escaping of quotes for check constraint expressions in MySQL schema by Flixt · Pull Request #42429 · rails/rails
MySQLを利用中、スキーマダンプ内のCHECK制約に含まれる一重引用符のエスケープが重複する(
\'
)問題を修正。CHECK制約に渡す式に引用符が既に含まれていると、mysql2アダプタのスキーマダンプが無効になっていた。
修正: #42424
Felix Tscheulin
同CHANGELOGより
🔗 Performance tune the SQLite3 adapter connection configuration by fractaledmind · Pull Request #49349 · rails/rails
SQLite3アダプタのコネクション設定のパフォーマンスを高速化。
Write-Ahead-Log(WAL)を
synchronous=NORMAL
モードで利用するようにし、ジャーナルサイズの上限(journal_size_limit
)、健全なサイズの共有メモリバッファ(mmap_size
)、共有キャッシュ(cache_size
)を設定したことで、Railsアプリケーションでのパフォーマンスが平均して2倍改善された。Stephen Margheim
同CHANGELOGより
参考: Enhancing your Rails app with SQLite | Fractaled Mind
参考: 週刊Railsウォッチ20231004: SQLite3アダプタのコネクション設定のパフォーマンスチューニング
🔗 Allow SQLite3 busy_handler
to be configured with simple max number of retries by fractaledmind · Pull Request #49352 · rails/rails
SQLite3の
busy_handler
で、retries
をシンプルに上限回数まで行える設定を追加。パフォーマンスが重要なアプリケーションでは、ビジーなコネクションを遅延なしで再試行するのが望ましい。
database.yml
のretries
値(integer)で指定した回数に達するまで、busy_handler
関数でビジーコネクションへの再接続を(待ち時間を指数増加せずに)試行するようになった。Stephen Margheim
同CHANGELOGより
🔗 Add SQLite3 support for supports_insert_returning?
by fractaledmind · Pull Request #49290 · rails/rails
SQLite3アダプタで
supports_insert_returning?
をサポート。
supports_insert_returning?
(AbstractAdapter
)を完全に実装することで、SQLite3アダプタでも自動生成カラム(#48241)とカスタム主キーをサポートする。Stephen Margheim
同CHANGELOGより
参考: Rails API ActiveRecord::ConnectionAdapters::AbstractAdapter
参考: 週刊Railsウォッチ20231004: SQLite3でsupports_insert_returning?
をサポート
🔗 Ensure the SQLite3 adapter handles default functions with the ||
concatenation operator by fractaledmind · Pull Request #49287 · rails/rails
SQLite3アダプタで、結合演算子
||
を含むデフォルト関数を処理できるようになった。従来は、デフォルト関数で
"'Ruby ' || 'on ' || 'Rails'"
のように静的な文字列が生成されていた。
改修によって、"Ruby on Rails"
を適切にアダプタに渡して利用できるようになった。change_column_default "test_models", "ruby_on_rails", -> { "('Ruby ' || 'on ' || 'Rails')" }
Stephen Margheim
同CHANGELOGより
参考: 週刊Railsウォッチ20231004: SQLite3の結合演算子||
をアダプタのデフォルト関数に渡せるようになった
🔗 dump PostgreSQL schemas as part of the schema dump by lsylvester · Pull Request #49164 · rails/rails
PostgreSQL固有のスキーマをschema.rbにダンプできるようにする
create_schema
を追加。Lachlan Sylvester
同CHANGELOGより
🔗 Active Record CHANGELOG(v7.1.0.beta1)
🔗 Encryption: support support_unencrypted_data
at a per-attribute level by ghiculescu · Pull Request #49072 · rails/rails
属性ごとに設定される
support_unencrypted_data
オプションを暗号化に追加。特定の暗号化済み属性だけを
support_unencrypted_data
で暗号化しないように設定可能になった。
このオプションは、ActiveRecord::Encryption.config.support_unencrypted_data == true
が設定済みの場合にのみ有効。class User < ActiveRecord::Base encrypts :name, deterministic: true, support_unencrypted_data: false encrypts :email, deterministic: true end
Alex Ghiculescu
同CHANGELOGより
参考: 週刊Railsウォッチ20230926: 暗号化属性の平文データサポートをsupport_unencrypted_data
オプションで属性ごとに無効化できるようになった
🔗 Instrument Active Record transactions by ipc103 · Pull Request #49192 · rails/rails
Active Recordのトランザクションでinstrumentation(計測)を利用可能になった。
トランザクションイベントをサブスクライブすることでトラッキングやinstrumentationで利用できるようになる。イベントペイロードには、コネクションの他にタイミングの詳細詳細情報も含まれる。
ActiveSupport::Notifications.subscribe("transaction.active_record") do |event| puts "Transaction event occurred!" connection = event.payload[:connection] puts "Connection: #{connection.inspect}" end
Daniel Colson, Ian Candy
同CHANGELOGより
参考: 週刊Railsウォッチ20230926: Active Recordのトランザクションをinstrumentationで計測できるようになった
参考: Active Support の Instrumentation 機能 - Railsガイド
🔗 Support composite foreign keys via migration helpers by fatkodima · Pull Request #47637 · rails/rails
マイグレーションヘルパーで複合主キーをサポート。
# "carts"テーブルの主キーが"(shop_id, user_id)"だとする add_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id]) remove_foreign_key(:orders, :carts, primary_key: [:shop_id, :user_id]) foreign_key_exists?(:orders, :carts, primary_key: [:shop_id, :user_id])
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20230926: マイグレーションヘルパーで複合主キーをサポート
🔗 Adds support for if_not_exists
when adding a check constraint. by ccutrer · Pull Request #49178 · rails/rails
マイグレーションにCHECK制約を追加するときの
if_not_exists
オプションをサポート。add_check_constraint :posts, "post_type IN ('blog', 'comment', 'share')", if_not_exists: true
Cody Cutrer
同CHANGELOGより
参考: 週刊Railsウォッチ20230926: マイグレーションのadd_check_constraint
にif_not_exists
オプションを渡せるようになった
🔗 [Fix #49055] Raise an ArgumentError
when #accepts_nested_attributes_for
is redeclared for an association by joshuay03 · Pull Request #49056 · rails/rails
注: このプルリクはその後0f7fe4aで取り消されました。
同じクラス内の関連付けに対して
#accepts_nested_attributes_for
が複数回宣言されるとArgumentError
を発生するようになった。
従来は、最後の宣言が以前の宣言をエラーなしでオーバーライドしていた。サブクラスでのオーバーライドは引き続き許可されている。Joshua Young
同CHANGELOGより
🔗 Deprecate passing rewhere
to merge
by HParker · Pull Request #45498 · rails/rails
#merge
メソッドのrewhere
オプションを非推奨化。
#merge
メソッドのrewhere
オプションは置き換えなしに非推奨化され、Rails 7.2で削除される予定。Adam Hess
同CHANGELOGより
参考: 週刊Railsウォッチ20230913: merge
にrewhere
オプションを渡すことが非推奨化された
🔗 Fix unscope not working when where by tripe dot range by ippachi · Pull Request #48095 · rails/rails
unscope
が特定のケース(トリプルドット...
)で動作しない問題を修正。修正前:
Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts` WHERE `posts`.`id` >= 1 AND `posts`.`id` < 3"
修正後:
Post.where(id: 1...3).unscope(where: :id).to_sql # "SELECT `posts`.* FROM `posts`"
修正:#48094
Kazuya Hatanaka
同CHANGELOGより
参考: 週刊Railsウォッチ20230913: where
でトリプルドット...
rangeを使うとunscope
が効かない問題を修正
🔗 Change has_secure_token
default to on: :initialize
by seanpdoyle · Pull Request #48912 · rails/rails
has_secure_token
のデフォルトをon: :initialize
に変更。新しいデフォルト値を
on: :create
からon: :initialize
に変更した。
この設定はconfig.active_record.generate_secure_token_on
コンフィグで変更可能。config.active_record.generate_secure_token_on = :create
Sean Doyle
同CHANGELOGより
参考: config.active_record.generate_secure_token_on
-- Rails アプリケーションを設定する - Railsガイド
🔗 Fix change_column not setting precision for sqlite by skipkayhil · Pull Request #49090 · rails/rails
7.0以降のマイグレーションとSQLiteを利用すると
change_column
でdatetime
カラムがprecision: 6
に設定されない問題を修正。Hartley McGuire
同CHANGELOGより
🔗 Support composite identifiers in to_key
by nvasilevski · Pull Request #48998 · rails/rails
to_key
で複合idをサポート。
#id
が既に配列の場合はto_key
で#id
値をArray
でラップしないようになる。Nikita Vasilevsky
同CHANGELOGより
参考: Rails API to_key
-- ActiveModel::Conversion
参考: Rails API to_key
-- ActiveRecord::AttributeMethods::PrimaryKey
🔗 Make enums validatable without raising error by mechnicov · Pull Request #49100 · rails/rails
enum
にvalidate
オプションを追加。class Contract < ApplicationRecord enum :status, %w[in_progress completed], validate: true end Contract.new(status: "unknown").valid? # => false Contract.new(status: nil).valid? # => false Contract.new(status: "completed").valid? # => true class Contract < ApplicationRecord enum :status, %w[in_progress completed], validate: { allow_nil: true } end Contract.new(status: "unknown").valid? # => false Contract.new(status: nil).valid? # => true Contract.new(status: "completed").valid? # => true
Edem Topuzov, Ryuta Kamizono
同CHANGELOGより
参考: 週刊Railsウォッチ20230913: Active Recordのenumにエラーをraiseしないvalidate
オプションが追加された
🔗 Use already loaded relation when batching if possible by HParker · Pull Request #48876 · rails/rails
in_batches
メソッドが、可能な場合に読み込み済みのリレーションを利用するようになった。既に読み込まれているリレーションでバッチメソッドを呼び出すと、データベースからレコードを再度取得せずに読み込み済みのレコードを使うようになる。
Adam Hess
同CHANGELOGより
参考: Rails API in_batches
-- ActiveRecord::Batches
🔗 Deprecate read_attribute(:id)
returning the primary key by adrianna-chang-shopify · Pull Request #49019 · rails/rails
主キーが
:id
でない場合にread_attribute(:id)
が主キーを返す振る舞いを非推奨化。Rails 7.2以後は、
read_attribute(:id)
はモデルの主キーに関係なくid
カラムの値を返すようになる。主キーの値を取得するには、代わりに#id
を使うこと。複合主キーモデルでは、read_attribute(:id)
は今後もid
カラムの値を返すようになる。Adrianna Chang
同CHANGELOGより
参考: 週刊Railsウォッチ20230906: 主キーが:id
でない場合に主キーを返すread_attribute(:id)
を非推奨化
🔗 Fix 6.1 change_table setting datetime precision by skipkayhil · Pull Request #48974 · rails/rails
マイグレーション6.1の
change_table
が設定するdatetime
カラムの精度を修正。Hartley McGuire
同CHANGELOGより
🔗 Fix 6.1 change_column setting datetime precision by skipkayhil · Pull Request #48969 · rails/rails
マイグレーション6.1の
change_column
が設定するdatetime
カラムの精度を修正。Hartley McGuire
同CHANGELOGより
🔗 Use alias_attribute
to provide id_value
alias for id
attribute by adrianna-chang-shopify · Pull Request #48930 · rails/rails
レコードの
id
カラムの生の値にアクセスするActiveRecord::Base#id_value
を追加。このエイリアスは、
:id
カラムを宣言しているモデルに対してのみ提供される。Adrianna Chang
同CHANGELOGより
参考: 週刊Railsウォッチ20230906: モデルのid
属性をid_value
で取得できるようになった
🔗 Fix tracking previous changes for ActiveRecord::Store accessors with underlying JSON data column by rdimartino · Pull Request #43386 · rails/rails
JSONで構造化されたデータ型を使うカラムにおける
ActiveRecord::Store
の直前の変更トラッキングを修正。従来は、JSONで構造化されたデータベース型を持っているカラムに対してストアが
store_accessor
として定義されていると、最後に保存したときの変更にアクセスする以下のメソッドが動作しなかった。
#saved_change_to_key?
#saved_change_to_key
#key_before_last_save
Robert DiMartino
同CHANGELOGより
🔗 Support NULLS NOT DISTINCT in Postgres 15+ by grjones · Pull Request #48608 · rails/rails
PostgreSQL 15以降のインデックスで
NULLS [NOT] DISTINCT
を完全サポート。前回の作業でマイグレーションでのインデックス作成は行えるようになっていたが、schema.rbではサポートされていなかった。また、
NULLS [NOT] DISTINCT
のマッチ順序が正しくなかったため、スキーマ検出が一定していなかった。Gregory Jones
同CHANGELOGより
参考: 週刊Railsウォッチ20230823: PostgreSQL 15のNULLS NOT DISTINCT
をサポート
参考: PostgreSQL 15.4ドキュメント CREATE INDEX
🔗 Allow escaping of literal colons in ActionRecord::Sanitization#replace_named_bind_variables
by f3ndot · Pull Request #48852 · rails/rails
名前付きバインド変数が使われている場合に
sanitize_sql_*
メソッドでコロン:
をエスケープするようになった。Justin Bull
同CHANGELOGより
参考: 週刊Railsウォッチ20230823: ActionRecord::Sanitization#replace_named_bind_variables
でコロン:をエスケープできるよう修正
🔗 Fix #previously_new_record?
on destroyed records by adrianna-chang-shopify · Pull Request #48796 · rails/rails
#previously_new_record?
が削除済みレコードでtrue
を返す問題を修正。従来は、レコードを作成してから削除すると
#previously_new_record?
がtrue
を返すことがあった。
修正後は、レコードに対するどのUPDATEおよびDELETEでも変更を考慮することで#previously_new_record?
がfalse
を返すようになった。Adrianna Chang
同CHANGELOGより
参考: この修正はRails 7.0.7でリリース済みです。
🔗 Specify when to generate has_secure_token
by seanpdoyle · Pull Request #47420 · rails/rails
has_secure_token
にon:
でコールバックを指定できるようになった。class User < ApplicationRecord has_secure_token on: :initialize end User.new.token # => "abc123...."
Sean Doyle
同CHANGELOGより
訳注: デフォルトはon: create
です。
参考: 週刊Railsウォッチ20230809: has_secure_token
を生成するタイミングを指定可能になった
🔗 Fix counter_cache create/concat with overlapping counter_cache_column by casperisfine · Pull Request #48665 · rails/rails
関連付けのカラムがオーバーラップしている場合のインメモリカウンタキャッシュの増加を修正。
2つの関連付けに名前の似ているカウンタキャッシュカラムがある場合、Active Recordが間違った方をインクリメントする可能性があった。
Jacopo Beschi, Jean Boussier
同CHANGELOGより
🔗 Don't show secrets for Active Record's Cipher::Aes256Gcm#inspect
. by p8 · Pull Request #48679 · rails/rails
Active Recordの
Cipher::Aes256Gcm#inspect
でsecretsを表示しないようになった。修正前:
ActiveRecord::Encryption::Cipher::Aes256Gcm.new(secret).inspect "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038 ... @secret="\xAF\bFh]LV}q\nl\xB2U\xB3 ... >"
修正後:
ActiveRecord::Encryption::Cipher::Aes256Gcm(secret).inspect "#<ActiveRecord::Encryption::Cipher::Aes256Gcm:0x0000000104888038>"
Petrik de Heus
同CHANGELOGより
参考: Rails API ActiveRecord::Encryption::Cipher::Aes256Gcm
🔗 Active Record commit transaction on return
, break
and throw
by casperisfine · Pull Request #48600 · rails/rails
トランザクションの振る舞いを非ローカルな
return
、break
、throw
でコミットする以前の振る舞いに戻した。Model.transaction do model.save return other_model.save # 実行されなくなった end
かつて、エラーが発生した場合にのみロールバックがトリガーされていた時代があったが、Ruby 2.3の
timeout
ライブラリが実行を中断するためにthrow
を使うようになり、オープン中のトランザクションがコミットされるという逆効果が生じていた。これを解決するために、Active Record 6.1ではトランザクションを(コミットではなく)ロールバックするように動作を変更していた(不完全なトランザクションをコミットする可能性よりも安全性が高いため)。
Rails 6.1以降は、transaction
ブロック内でのreturn
やbreak
やthrow
の利用は根本的に非推奨となっていた。しかし、
timeout 0.4.0
のリリースにより、Timeout.timeout
で(throw
ではなく)再びエラーをraiseするようになった。これによって、Active Recordの振る舞いを当初の(驚きの少ない)動作に戻すことが可能になった。Rails 6.1より前の「歴史的な」振る舞いは、以下の設定で有効にできる。
Rails.application.config.active_record.commit_transaction_on_non_local_return = true
また、Rails 7.1で作成する新規アプリケーションはデフォルトでこの振る舞いになる。
Jean Boussier
同CHANGELOGより
参考: Deprecate committing a transaction exited with return or throw by dylanahsmith · Pull Request #29333 · rails/rails
参考: config.active_record.commit_transaction_on_non_local_return
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20230809: トランザクションがreturn
、break
、throw
でコミットするようになった
以下はRails 6.1で振る舞いが変更されたときの記事です。
🔗 Deprecate name
argument in remove_connection
by eileencodes · Pull Request #48681 · rails/rails
#remove_connection
のname
引数を非推奨化。
#remove_connection
のname
引数は置き換えなしで非推奨化された。
#remove_connection
は、コネクションを確立するクラスで直接呼び出されるべき。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API remove_connection
-- ActiveRecord::ConnectionHandling
🔗 Fix has_one through singular building with inverse. by gmcgibbon · Pull Request #48674 · rails/rails
単数形の逆関連付けを経由する
has_one
through:
関連付けでレコードをビルド可能になった。
belongs_to
through:
関連付けでは、外部キーを主キーのモデルにリンクする必要はない。
has_one
の場合はこの関連付けがミュータブルではないため、レコードをビルドできなかった。Gannon McGibbon
同CHANGELOGより
参考: 週刊Railsウォッチ20230802: belongs_to :inverse_of
を介したhas_one :through
関連付けで、レコードをビルドできるように修正
🔗 Disable database prepared statements when query logs are enabled by zzak · Pull Request #48631 · rails/rails
データベースでクエリログが有効な場合はプリペアドステートメントを無効にするようになった。
クエリログは毎回一意のクエリを作成するため、プリペアドステートメントとクエリログは互換性がない。
zzak, Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20230802: クエリログが有効な場合はプリペアドステートメントを無効にするよう修正
🔗 Add a encryption option to support previous data encrypted non-deterministically with a SHA1 hash digest by jorgemanrubia · Pull Request #48530 · rails/rails
SHA1ハッシュダイジェストで非決定論的に暗号化された既存データの復号をサポート
これにより、Active Recordの新しい暗号化オプションが追加され、SHA1ハッシュダイジェストで非決定論的に暗号化されたデータを復号できるようになる。
Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
新しいオプションは、7.0から7.1にアップグレードする際の問題に対処する。Active Record暗号化の初期化方法にバグがあったため、非決定論的暗号化に用いるキープロバイダは、Railsが
Rails.application.config.active_support.key_generator_hash_digest_class
でグローバルに設定したものではなく、SHA-1をダイジェストクラスとして利用していた。Cadu Ribeiro and Jorge Manrubia
同CHANGELOGより
参考: config.active_record.encryption.support_sha1_for_non_deterministic_encryption
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20230725: SHA1ハッシュダイジェストで非決定論的に暗号化された従来のデータの復号をサポート
🔗 Adding PG enum drop, rename, add value, rename value by rayfaddis · Pull Request #44898 · rails/rails
PostgreSQLのマイグレーションでenumのリネーム、値の追加、値のリネームが可能になった。
rename_enum
およびrename_enum_value
はリバース可能である。add_enum_value
はPostgreSQLの制約(enum値を削除できない)によりリバースできない。代替手段として、enum全体を削除してから再作成すること。rename_enum :article_status, to: :article_state
add_enum_value :article_state, "archived" # will be at the end of existing values add_enum_value :article_state, "in review", before: "published" add_enum_value :article_state, "approved", after: "in review"
rename_enum_value :article_state, from: "archived", to: "deleted"
Ray Faddis
同CHANGELOGより
🔗 Allow composite primary key to be derived from schema by nvasilevski · Pull Request #47633 · rails/rails
スキーマから複合主キーを導出可能になった。
複合主キーを含むスキーマを持つアプリケーションを起動したときにwarningが発生しないようになり、
ActiveRecord::Base#primary_key
の値がnil
になることもなくなる。
以下のようなtravel_routes
テーブル定義とTravelRoute
モデルがあるとする。create_table :travel_routes, primary_key: [:origin, :destination], force: true do |t| t.string :origin t.string :destination end class TravelRoute < ActiveRecord::Base; end
この
TravelRoute.primary_key
の値は自動的に["origin", "destination"]
に導出される。Nikita Vasilevsky
同CHANGELOGより
参考: 週刊Railsウォッチ20230628: スキーマから複合主キーを導出可能になった
🔗 Store connection_pool
in database-related exceptions by luanzeba · Pull Request #48295 · rails/rails
connection_pool
にコネクションアダプタからraiseされる例外を保存するようになった。例外を引き起こしたコネクションや、ロール、シャードなどのコンテキストが
connection_pool
に追加される。Luan Vieira
同CHANGELOGより
参考: 週刊Railsウォッチ20230628: データベース関連の例外をconnection_pool
に保存するようになった
🔗 Support batching using composite primary keys and multiple column ordering by TakuyaKurimoto · Pull Request #48268 · rails/rails
複合主キーを持つテーブルの
find_each
、find_in_batches
、in_batches
で:asc
、:desc
を指定可能になった。複合主キーがあるテーブルで
find_each
、find_in_batches
、in_batches
を実行するときに、キーごとに:asc
や:desc
を指定可能になる。Person.find_each(order: [:desc, :asc]) do |person| person.party_all_night! end
Takuya Kurimoto
同CHANGELOGより
参考: 週刊Railsウォッチ20230628: 複合主キーを持つテーブルのfind_each
、find_in_batches
、in_batches
で:asc
、:desc
を指定可能になった
🔗 Fix polymorphic association subquery by lazaronixon · Pull Request #48362 · rails/rails
has_one
/has_many
ポリモーフィックリレーションの関連付けにおけるwhere
の振る舞いを修正。修正前:
Treasure.where(price_estimates: PriceEstimate.all) #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
修正後:
Treasure.where(price_estimates: PriceEstimate.all) #=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
Lázaro Nixon
同CHANGELOGより
この修正は、Rails 7.0.6でリリース済みです。
🔗 Assign auto populated columns on Active Record object creation by nvasilevski · Pull Request #48241 · rails/rails
Active Recordでのレコード作成時に自動生成カラムを割り当てられるようになる。
レコード作成ロジックを変更することで、
auto_increment
カラムをレコード作成時に割り当て可能にする。これによって、モデルの主キーへのリレーションにかかわらず、レコード作成直後にauto_increment
カラムを割り当てられるようになる。この変更によるメリットが最も大きいのはPostgreSQLアダプタで、
RETURNING
ステートメントを利用するレコードのINSERT
後に、任意の個数の自動生成カラムをオブジェクトに割り当てられるようになる。Nikita Vasilevsky
同CHANGELOGより
参考: その後#49290でSQLite3でも自動生成カラムをサポートしました。
参考: 週刊Railsウォッチ20230621: オブジェクト作成時にデータベース側の自動入力属性を割り当て可能にする
🔗 Set default_shard from connects_to hash by eileencodes · Pull Request #48353 · rails/rails
connected_to
のshards
ハッシュの最初のキーをdefault_shard
で使うようになった。アプリケーションによっては、コネクションモデルのシャード名に
:default
を使いたくない場合がある。残念なことに、Active Recordはプールマネージャから正しいコネクションを得るために何らかのシャードを仮定しなければならないため、:default
シャードの存在を期待する。アプリケーションで強制的に手動設定する代わりに、
connects_to
がシャードのハッシュからデフォルトシャード名を推測して、最初のシャードをデフォルトであると仮定するようになる。たとえば以下のようなモデルがあるとする。
class ShardRecord < ApplicationRecord self.abstract_class = true connects_to shards: { shard_one: { writing: :shard_one }, shard_two: { writing: :shard_two } }
これで、このクラスの
default_shard
がshard_one
に設定されるようになる。修正: #45390
Eileen M. Uchitelle
同CHANGELOGより
参考: 週刊Railsウォッチ20230621: connected_to
のshards
ハッシュの最初のキーをdefault_shard
で使うようになった
🔗 Fix change_in_place? for binary serialized columns by casperisfine · Pull Request #48274 · rails/rails
背後のカラムがバイナリエンコードになっているシリアライズ属性での変更検出を修正。
Jean Boussier
同CHANGELOGより
この修正は、Rails 7.0.5でリリース済みです。
参考: 週刊Railsウォッチ20230613: change_in_place?
の挙動を修正
🔗 Implement ActiveRecord.disconnect_all!
to close all connections by casperisfine · Pull Request #47856 · rails/rails
全コネクションプールにある全コネクションを即座にクローズする
ActiveRecord.disconnect_all!
を追加。Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20230613: マルチプルDBで使えるActiveRecord.disconnect_all!
が追加
🔗 Discard connections which may be left in a transaction by nicholasdower · Pull Request #48200 · rails/rails
トランザクションに残っているコネクションを破棄する機能を改善。
エラーが原因で、
within_new_transaction
のコネクションがオープン中のトランザクションに予期せず残ってしまうことがある。そうなるとコネクションが再利用されてしまい、以下のようなエラーが発生する可能性がある。
- 書き込みが実際は成功しているにもかかわらず失敗したように見える
- 書き込みが実際は失敗しているにもかかわらず成功したように見える
- 読み込んだデータが古い、またはコミットされていない
従来は以下のケースについては検出されていた。
- トランザクション内でエラーが発生し、ロールバックを試行中に別のエラーが発生した場合
改修によって、以下のケースも検出されるようになった。
- トランザクションの開始直後にエラーが発生した場合
- トランザクションのコミット中にエラーが発生し、ロールバックを試行中に別のエラーが発生した場合
- トランザクションのロールバック中にエラーが発生した場合
Nick Dower
同CHANGELOGより
🔗 Make Active Record's query cache an LRU by casperisfine · Pull Request #48110 · rails/rails
Active Recordのクエリキャッシュが直近で最も利用頻度の低い(LRU: least recently used)エントリを削除するようになった。
デフォルトでは、最も直近で利用された
100
件のクエリのみを維持する。
このキャッシュサイズはdatabase.yml
で変更可能。development: adapter: mysql2 query_cache: 200
クエリキャッシュそのものを無効にすることも可能。
development: adapter: mysql2 query_cache: false
Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20230607: 保持するクエリキャッシュを直近50件までに変更した
🔗 Deprecate check_pending!
in favor of check_all_pending!
by eileencodes · Pull Request #48134 · rails/rails
check_pending!
を非推奨化。今後はcheck_all_pending!
を使うこと。
check_pending!
が保留中のマイグレーションをチェックする対象は、現在の(または渡された)データベースコネクションのみでマルチプルデータベースに対応していない。このcheck_pending!
は非推奨化される。今後は、指定の環境にある複数のデータベース設定ですべての保留中マイグレーションをチェックするcheck_all_pending!
を使うこと。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API check_all_pending!
-- ActiveRecord::Migration
🔗 Make increment_counter
/decrement_counter
accept an amount argument by fatkodima · Pull Request #48128 · rails/rails
increment_counter
やdecrement_counter
にby:
オプションで増分値を渡せるようになった。Post.increment_counter(:comments_count, 5, by: 3)
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20230607: Active Recordのカウンタインクリメントやデクリメントに1以外の増分量を効果的に指定できるようになった
🔗 Add intersects?
to Relation
by john-h-k · Pull Request #47670 · rails/rails
Array#intersect?
をActiveRecord::Relation
に追加。
Array#intersect?
はRuby 3.1以降でのみ利用可能。これにより、
ActiveRecord::Relation
でRuboCopのStyle/ArrayIntersect
copを利用できるようになる。John Harry Kelly
同CHANGELOGより
参考: 週刊Railsウォッチ20230524: ActiveRecord::Relation
にintersects?
が追加された
🔗 deferrable foreign key can be passed to references by alpaca-tc · Pull Request #47671 · rails/rails
マイグレーションで
deferrable
オプション(先延ばし可能)を有効にした外部キーをt.references
に渡せるよう修正。Hiroyuki Ishii
同CHANGELOGより
参考: 週刊Railsウォッチ20230524: マイグレーションでreferences
にdeferrable
オプション付きの外部キーを渡しても無視される問題を修正
🔗 Deprecate deferrable: true
option of add_foreign_key
by alpaca-tc · Pull Request #47659 · rails/rails
関連: #46192
add_foreign_key
のdeferrable: true
オプションを非推奨化。非推奨化された
deferrable: true
オプションはRails 7.2で削除される予定。今後はdeferrable: :immediate
が推奨される。非推奨化の理由は、
deferrable: true
とdeferrable: :deferred
の意味がわかりにくいため(どちらの値もtruthyに見えてしまう)。推奨される
deferrable: :immediate
の振る舞いは、#46192で追加されたadd_unique_key
のdeferrable
オプションと同じ。Hiroyuki Ishii
同CHANGELOGより
参考: 週刊Railsウォッチ20230524: add_foreign_keyのdeferrable: trueオプションを非推奨化する
🔗 Make Adapter#exec_query clear the query cache by casperisfine · Pull Request #48069 · rails/rails
AbstractAdapter
の#execute
と#exec_query
でクエリキャッシュをクリアするよう修正。リードオンリーのSQLクエリをクエリキャッシュをクリアせずに実行する必要がある場合は、
AbstractAdapter#select_all
を使うこと。Jean Boussier
同CHANGELOGより
参考: Rails API select_all
-- ActiveRecord::ConnectionAdapters::DatabaseStatements
🔗 Add CTE support for joins by palkan · Pull Request #46843 · rails/rails
関連: Common Table Expression support added "out-of-the-box" by vlado · Pull Request #37944 · rails/rails
.joins
や.left_outer_joins
もCTE(Common Table Expression)で使えるようになった。例:
Post .with(commented_posts: Comment.select(:post_id).distinct) .joins(:commented_posts) #=> WITH (...) SELECT ... INNER JOIN commented_posts on posts.id = commented_posts.post_id
Vladimir Dementyev
同CHANGELOGより
参考: §Common Table Expression -- Hierarchical and recursive queries in SQL - Wikipedia
参考: 週刊Railsウォッチ20230524: joins
でCTEをサポート
🔗 Add load hook for ActiveRecord::ConnectionAdapters::Mysql2Adapter
by fatkodima · Pull Request #48012 · rails/rails
ActiveRecord::ConnectionAdapters::Mysql2Adapter
(名前はactive_record_mysql2adapter
)にloadフックを追加。これにより、ActiveRecord::ConnectionAdapters::Mysql2Adapter
の一部をオーバーライド可能になり、既にloadフックを備えているPostgreSQLAdapter
やSQLite3Adapter
と統一される。fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20230524: Mysql2Adapter
にloadフックを追加
🔗 Introduce adapter for Trilogy, a MySQL-compatible DB client by adrianna-chang-shopify · Pull Request #47880 · rails/rails
Trilogyデータベースクライアント用のアダプタを導入。
TrilogyはMySQL互換のデータベースクライアント。Railsアプリケーションの
config/database.yml
ファイルを以下のように設定することでTrilogyを利用できる。development: adapter: trilogy database: blog_development pool: 5
または、以下のように
DATABASE_URL
環境変数による設定でも利用できる。ENV['DATABASE_URL'] # => "trilogy://localhost/blog_development?pool=5"
Adrianna Chang
同CHANGELOGより
参考: 週刊Railsウォッチ20230502: Trilogyデータベースクライアント用のアダプタが導入される
🔗 Run after_commit
callbacks defined on models in the correct order by ghiculescu · Pull Request #46992 · rails/rails
モデルで定義されている
after_commit
コールバックが、定義順に正しく実行されるようになった。class User < ActiveRecord::Base after_commit { puts("これが最初に呼ばれる") } after_commit { puts("これが次に呼ばれる") } end
従来のコールバックは逆順で実行されていた。以下のコンフィグで新しい振る舞いを有効にできる。
config.active_record.run_after_transaction_callbacks_in_order_defined = true
新規アプリでは、これがデフォルトの振る舞いになる。
Alex Ghiculescu
同CHANGELOGより
🔗 Infer foreign_key
when inverse_of
is present by Tiedye · Pull Request #47797 · rails/rails
has_one
関連付けやhas_many
関連付けでinverse_of
が指定されている場合にforeign_key
を推論するようになった。has_many :citations, foreign_key: "book1_id", inverse_of: :book
上を以下のようにシンプルに書けるようになる。
has_many :citations, inverse_of: :book
foreign_key
は、対応するbelongs_to
関連付けから読み取られる。Daniel Whitney
同CHANGELOGより
参考: 週刊Railsウォッチ20230412: has_one
やhas_many
にinverse_of
が存在する場合にforeign_key
を推論するようになった
🔗 Fix Rails generated index name being too long by mscoutermarsh · Pull Request #47753 · rails/rails
自動生成されるインデックス名の長さに上限が設定されるようになった。
自動生成されるインデックス名は最大62バイトになった。この長さは、MySQL、PostgreSQL、SQLite3のインデックス名のデフォルトの最大長さに収まる。
インデックス名がこの上限を超えた場合は自動的に短縮される。
変更前(長すぎる):
index_testings_on_foo_and_bar_and_first_name_and_last_name_and_administrator
変更後(短縮形):
idx_on_foo_bar_first_name_last_name_administrator_5939248142
短縮形には、インデックス名がデータベースで一意になるようハッシュが追加される。
Mike Coutermarsh
同CHANGELOGより
参考: 週刊Railsウォッチ20230425: 自動生成されるインデックス名を上限で切り詰めるようになった
🔗 Implement marshal_dump
and marshal_load
on ActiveRecord::Base by casperisfine · Pull Request #47747 · rails/rails
安定性が高く最適化されたMarshalシリアライザがActive Recordモデルに導入された。
以下のコンフィグで有効になる。
config.active_record.marshalling_format_version = 7.1
Jean Boussier
同CHANGELOGより
参考: config.active_record.marshalling_format_version
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20230412: ActiveRecord::Base
にmarshal_dump
とmarshal_load
を実装
🔗 Introduce query-by-tuple syntax by paarthmadan · Pull Request #47729 · rails/rails
複合主キー向けの"タプル"構文を
where
に導入。
where
を用いるクエリで新しいタプル(tuple)構文が使えるようになった。これは、キーに「カラムの配列」、値に「それに対応するタプルの配列」をそれぞれ渡せる。
このキーではカラムのリストを指定するが、値はそのカラムリストに適合する順序付きタプルの配列となる。
例:# Cpk::Book => Cpk::Book(author_id: integer, number: integer, title: string, revision: integer) # Cpk::Book.primary_key => ["author_id", "number"] book = Cpk::Book.create!(author_id: 1, number: 1) Cpk::Book.where(Cpk::Book.primary_key => [[1, 2]]) # => [book] # Topic => Topic(id: integer, title: string, author_name: string...) Topic.where([:title, :author_name] => [["The Alchemist", "Paul Coelho"], ["Harry Potter", "J.K Rowling"]])
Paarth Madan
同CHANGELOGより
参考: 週刊Railsウォッチ20230412: 複合主キー向けの"タプル"構文をwhere
に導入
🔗 Allow SQL Warnings to be ignored using error codes by nickborromeo · Pull Request #47650 · rails/rails
SQL警告メッセージをエラーコードでフィルタできるようになった。
以下のActive Recordコンフィグで特定の警告コードを無視できる。
# 常に無視すべき警告の許可リストを設定する config.active_record.db_warnings_ignore = [ "1062", # MySQL Error 1062: Duplicate entry ]
この機能はMySQLアダプタとPostgreSQLアダプタでサポートされる。
Nick Borromeo
同CHANGELOGより
参考: config.active_record.db_warnings_ignore
-- Rails アプリケーションの設定項目 - Railsガイド
参考: 週刊Railsウォッチ20230412: SQL警告メッセージをエラーコードでフィルタできるようになった
🔗 Run a load hook when TestFixtures is included by andrewn617 · Pull Request #47690 · rails/rails
:active_record_fixtures
遅延読み込みフックを導入。この名前で定義したフックは、クラスに
TestFixtures
がinclude
されると常に実行されるようになる。ActiveSupport.on_load(:active_record_fixtures) do self.fixture_paths << "test/fixtures" end klass = Class.new klass.include(ActiveRecord::TestFixtures) klass.fixture_paths # => ["test/fixtures"]
Andrew Novoselac
同CHANGELOGより
参考: 週刊Railsウォッチ20230412: TestFixtures
をinclude
するたびにloadフックを実行するように修正
🔗 Introduce TestFixtures#fixture_paths by andrewn617 · Pull Request #47675 · rails/rails
TestFixtures
に#fixture_paths
(複数形)を追加。
#fixture_paths
アクセサを使うことで、複数のフィクスチャパスを指定できるようになった。
アプリは引き続きデフォルトでtest/fixtures
を単一のフィクスチャパスとして持つが、追加のフィクスチャパスも指定できるようになる。ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures" ActiveSupport::TestCase.fixture_paths << "component2/test/fixtures"
TestFixtures#fixture_path
(単数形)は非推奨化された。Andrew Novoselac
同CHANGELOGより
参考: 週刊Railsウォッチ20230405: fixtureパスをRailsエンジン単位で指定可能になった
🔗 Adds support for deferrable exclude constraints in PostgreSQL. by alpaca-tc · Pull Request #47655 · rails/rails
PostgreSQLの
EXCLUDE
制約でDEFERRABLE
をサポート。デフォルトでは、PostgreSQLの
EXCLUDE
制約は個別のステートメントの後でチェックされる。
ほとんどのユースケースではこれで上手くいくが、以下のように範囲がオーバーラップする複数のステートメントを用いてレコードを置き換える場合は大きな制限となる。exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :immediate
deferrable: :immediate
を指定すると、制約が個別のステートメントの後でチェックされる。
しかしトランザクション内でSET CONSTRAINTS ALL DEFERRED
を用いてチェックを手動で延期すれば、トランザクション終了後にEXCLUDE
制約をチェックするようになる。これと同じことを、以下のようにデフォルトの振る舞いを
immediate
チェック(=個別のステートメントの後でチェックする)からdeferred
チェック(=トランザクション終了後にチェックする)に変更することでも可能になった。exclusion_constraint :users, "daterange(valid_from, valid_to) WITH &&", deferrable: :deferred
Hiroyuki Ishii
同CHANGELOGより
参考: PostgreSQL 15ドキュメント SET CONSTRAINTS
🔗 Delegated Type supports customizeable foreign_type column by jasonkarns · Pull Request #45041 · rails/rails
delegated_type
にforeign_type
オプションを渡すことで{role}_class
メソッドに反映されるようになった。
foreign_type
オプションを渡すことで、delegated_type
で標準でない{role}_type
カラム名を利用できるようになった。
このオプションは、delegated_type
がラップしている背後のbelongs_to
関連付けへforwardされるforeign_type
と同じ。Jason Karns
同CHANGELOGより
参考: 週刊Railsウォッチ20230405: Delegated Typesでカスタムカラム名を指定するforeign_type
オプションが追加された
🔗 Add support for unique constraints (PostgreSQL-only). by alpaca-tc · Pull Request #46192 · rails/rails
関連: Adds support USING INDEX
for unique constraints in PostgreSQL. by alpaca-tc · Pull Request #47971 · rails/rails
関連: Deprecate deferrable: true
option of add_foreign_key
by alpaca-tc · Pull Request #47659 · rails/rails
UNIQUE制約のサポートを追加(PostgreSQLのみ)。
add_unique_key :sections, [:position], deferrable: :deferred, name: "unique_section_position" remove_unique_key :sections, name: "unique_section_position"
UNIQUE制約に関しては、PostgreSQLのUNIQUE制約のドキュメントを参照。
デフォルトでは、PostgreSQLでのユニーク制約は個別のステートメントの後にチェックされる。
ほとんどの場合はこれで問題ないが、複数のステートメントを利用してレコードのuniqueカラムを置換する場合には大きな成約となる。以下の例では、レコード間でuniqueカラムを交換している。
# このpositionはuniqueカラム old_item = Item.create!(position: 1) new_item = Item.create!(position: 2) Item.transaction do old_item.update!(position: 2) new_item.update!(position: 1) end
デフォルトの振る舞いでは、最初の
UPDATE
ステートメントを実行する時点で失敗する。マイグレーションで以下のように
add_unique_key
に:deferrable
オプションを渡すことで、このチェックを先延ばしできるようになった。add_unique_key :items, [:position], deferrable: :immediate
deferrable: :immediate
を指定しても、振る舞いは最初の例と変わらないが、トランザクション内でSET CONSTRAINTS ALL DEFERRED
を使ってこのチェックを手動で先延ばしできるようになる。
これにより、UNIQUE制約がトランザクションの完了後にチェックされるようになる。また、以下のように
deferrable: :deferred
を指定することで、個別のステートメント後にチェックするデフォルトの振る舞いを、トランザクション完了後にチェックする先延ばしチェックに変更することも可能。add_unique_key :items, [:position], deferrable: :deferred
既存のuniqueインデックスを先延ばし可能にしたい場合は、以下のように
:using_index
オプションを渡すことで先延ばし可能なUNIQUE制約を作成できる。add_unique_key :items, deferrable: :deferred, using_index: "index_items_on_position"
Hiroyuki Ishii
同CHANGELOGより
参考: 週刊Railsウォッチ20230502: PostgreSQL: UNIQUE制約でUSING INDEXをサポート
🔗 Remove deprecated Tasks::DatabaseTasks.schema_file_type
· rails/rails@049dfd4
関連: Remove deprecated methods in ``Tasks::DatabaseTasks` · rails/rails@71f61b1
非推奨化されていた
Tasks::DatabaseTasks.schema_file_type
を削除。Rafael Mendonça França
同CHANGELOGより
🔗 Remove deprecated config.active_record.partial_writes
· rails/rails@96b9fd6
非推奨化されていた
config.active_record.partial_writes
を削除。Rafael Mendonça França
同CHANGELOGより
🔗 Remove deprecated ActiveRecord::Base
config accessors · rails/rails@96c9db1
非推奨化されていた
ActiveRecord::Base
コンフィグのアクセサメソッドを削除。Rafael Mendonça França
同CHANGELOGより
🔗 Allow configs_for to accept a custom hash key by eileencodes · Pull Request #47536 · rails/rails
configs_for
から:include_replicas
引数を削除。今後は:include_hidden
を使うこと。Eileen M. Uchitelle
同CHANGELOGより
アプリケーションのコンフィグをカスタムのハッシュキーで検索できるようになった。
カスタム設定を登録した場合や、ハッシュが特定のキーとマッチする設定を見つけたい場合は、
configs_for
にconfig_key
オプションを渡せるようになった。
たとえば、キーがvitess
のdb_config
がある場合、そのキーにマッチするデータベース設定のハッシュを以下のように検索できる。ActiveRecord::Base.configurations.configs_for(env_name: "development", name: "primary", config_key: :vitess) ActiveRecord::Base.configurations.configs_for(env_name: "development", config_key: :vitess)
Eileen M. Uchitelle
同CHANGELOGより
参考: 週刊Railsウォッチ20230322: データベース設定のカスタムハンドラを登録可能になった
🔗 Allow applications to register custom database configurations by eileencodes · Pull Request #47522 · rails/rails
アプリケーションでカスタムのデータベース設定ハンドラを登録できるようになった。
データベース設定がカスタムメソッドに応答するようにカスタマイズしたい場合に、カスタムハンドラを登録する仕組みを追加する。これは、Rails以外のデータベースアダプタやVitessなどのツールで、標準の
HashConfig
やUrlConfig
とは異なる方法で設定したい場合に有用。以下のデータベースYAMLで、
primary
データベースをUrlConfig
にしたまま、animals
dbでCustomConfig
オブジェクトを作成したいとする。development: primary: url: postgres://localhost/primary animals: url: postgres://localhost/animals custom_config: sharded: 1
カスタムハンドラを登録するには、最初にカスタムメソッドを持つクラスを作成する。
class CustomConfig < ActiveRecord::DatabaseConfigurations::UrlConfig def sharded? custom_config.fetch("sharded", false) end private def custom_config configuration_hash.fetch(:custom_config) end end
次にこのコンフィグをイニシャライザで登録する。
ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config| next unless config.key?(:custom_config) CustomConfig.new(env_name, name, url, config) end
これで、アプリケーションが起動すると、
:custom_config
キーの設定ハッシュがCustomConfig
オブジェクトになり、sharded?
に応答するようになる。アプリケーションは、Active Recordでこのカスタムハンドラが利用されるように条件を処理する必要がある。Eileen M. Uchitelle and John Crepezzi
同CHANGELOGより
参考: 週刊Railsウォッチ20230322: データベース設定のカスタムハンドラを登録可能になった
🔗 Stop serializing columns as YAML by default by casperisfine · Pull Request #47422 · rails/rails
ActiveRecord::Base.serialize
のデフォルトがYAMLでなくなった。YAMLのパフォーマンスは高くないうえに、注意しないとセキュリティ上の問題を引き起こす可能性がある。
残念ながら、Rubyの標準ライブラリには置き換えに適したシリアライザがない。
明らかな選択肢としてはJSONがあり、このユースケースには適したフォーマットだが、Ruby標準ライブラリのJSONシリアライザは厳密性が十分ではない(未知の型を文字列にキャストする形でフォールバックするため、データが破損する可能性がある)。
Oj
などのサードパーティJSONライブラリは、これに適したstrictモードを備えている。ユーザーは、自分たちの制約に基づいてシリアライザを選択することが望ましい。
従来のデフォルト設定に戻したい場合は、以下を設定する。
config.active_record.default_column_serializer = YAML
Jean Boussier
同CHANGELOGより
参考: config.active_record.default_column_serializer
-- Rails アプリケーションを設定する - Railsガイド
🔗 Allow to define the default column serializer by casperisfine · Pull Request #47463 · rails/rails
ActiveRecord::Base.serialize
のシグネチャが変更された。
serialize
に、2個の可能な値を渡せる単一の第2位置引数ではなく、2種類のキーワード引数(coder
とtype
)を渡せるように変更された。変更前:
serialize :content, JSON serialize :backtrace, Array
変更後:
serialize :content, coder: JSON serialize :backtrace, type: Array
Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20230314: デフォルトのカラムシリアライザを定義可能になった
🔗 YAMLColumn: use YAML.safe_dump
if available by casperisfine · Pull Request #47103 · rails/rails
YAMLカラムで可能な場合は
YAML.safe_dump
を使うようになった。
psych 4.0.1
以降、YAML.safe_load
と同様の型制約を利用可能で、使いやすいYAML.safe_dump
を適用可能になった。最初にシリアライズするときは、許可された型だけをペイロードで使うことが望ましい。そうしないと、データベース内に無効なレコードが残る可能性がある。
Jean Boussier
同CHANGELOGより
🔗 ActiveRecord::QueryLogs: handle invalid encoding by casperisfine · Pull Request #47214 · rails/rails
ActiveRecord::QueryLogs
における壊れたエンコーディングの処理を改善。BLOBフィールドを含むクエリをビルドするときにバイナリデータが含まれることがよくある。文字列がASCII-8BITで慎重にエンコードされない限り、通常は
UTF-8
でエンコードされてQueryLogs
が失敗する可能性があった。この修正により、
ActiveRecord::QueryLogs
はクエリの正しいエンコードに依存しなくなった。Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20230221: クエリのエンコードが壊れている場合のActiveRecord::QueryLogs
の処理を改善
🔗 Model Generator Source Paths Should Allow for Customization by spencerneste · Pull Request #47181 · rails/rails
create_table_migration
テンプレートのオーバーライドがActiveRecord::Generators::ModelGenerator
で反映されないバグを修正。rails g model create_books title:string content:text
修正により、上のジェネレータが以下の場所からこの順序で
create_table_migration.rb.tt
テンプレートを読み込むようになった。lib/templates/active_record/model/create_table_migration.rb lib/templates/active_record/migration/create_table_migration.rb
Spencer Neste
同CHANGELOGより
参考: 週刊Railsウォッチ20230613: モデルのジェネレータにcreate_table_migration
テンプレートのオーバーライドが正しく反映されない問題を修正
🔗 ActiveRecord::Relation#explain accepts options by reid-rigo · Pull Request #47043 · rails/rails
ActiveRecord::Relation
の#explain
にオプションを渡せるようになった。
explain
に:analyze
オプションやverbose
オプションを渡すことで、クエリプラン分析を詳細に行えるようになった。現在サポートされているデータベースおよびアダプタはPostgreSQLとMySQL。Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)
Reid Lynch
同CHANGELOGより
Rails 7.1: ActiveRecord::Relation#explainに:verboseや:analyzeオプションが追加(翻訳)
🔗 Add Arel functionality for "stitching together" SQL by olefriis · Pull Request #46948 · rails/rails
複数の
Arel::Nodes::SqlLiteral
ノードを互いに追加してArel::Nodes::Fragments
ノードを形成できるようになった。これにより、多くのSQLスニペットを結合できるようになる。Matthew Draper, Ole Friis
同CHANGELOGより
🔗 ActiveRecord::Base#signed_id
: raise if called on a new record by ghiculescu · Pull Request #47027 · rails/rails
新規レコードで
ActiveRecord::Base
の#signed_id
が呼び出されたらエラーを発生するようになった。従来は
id = nil
を元にしていたため、利用できないIDを返すことがあった。Alex Ghiculescu
同CHANGELOGより
🔗 Allow SQL warnings to be reported. by adrianna-chang-shopify · Pull Request #46690 · rails/rails
SQLのwarningを通知できるようにした。
以下のActive Recordコンフィグを設定することで、SQL warningの通知が有効になる。
# SQLクエリでwarningが発生した場合の操作を設定する config.active_record.db_warnings_action = :raise # warningの許可リストを設定する(設定したwarningは常に無視される) config.active_record.db_warnings_ignore = [ /Invalid utf8mb4 character string/, "An exact warning message", ]
この機能はMySQLアダプタとPostgreSQLアダプタでサポートされる。
Adrianna Chang, Paarth Madan
同CHANGELOGより
参考: config.active_record.db_warnings_action
-- Rails アプリケーションを設定する - Railsガイド
参考: config.active_record.db_warnings_ignore
-- Rails アプリケーションを設定する - Railsガイド
🔗 Add regroup method to ActiveRecord by dvisockas · Pull Request #47010 · rails/rails
#regroup
クエリメソッドを追加。これは.unscope(:group).group(fields)
のショートハンド。例:
Post.group(:title).regroup(:author) # SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
Danielius Visockas
同CHANGELOGより
参考: 週刊Railsウォッチ20230207: Active Recordにregroup
メソッドとregroup!
メソッドが追加された
🔗 Adds schema parameter into enable_extension by lomefin · Pull Request #46894 · rails/rails
PostgreSQLアダプタの
enable_extension
メソッドで、他のスキーマによってインストールされていなければならないPostgreSQL拡張をスキーマ名.拡張名
形式で指定できるようになった。例:
enable_extension('heroku_ext.hstore')
Leonardo Luarte
同CHANGELOGより
🔗 Add support for :include
index option by steve-abrams · Pull Request #44803 · rails/rails
マイグレーションの
add_index
に:include
オプションを追加(PostgreSQLのみ)。PostgreSQLの
INCLUDE
(キーでないカラムをインデックスに含める)のサポートを追加。add_index(:users, :email, include: [:id, :created_at])
上は以下を生成する。
CREATE INDEX index_users_on_email USING btree (email) INCLUDE (id, created_at)
Steve Abrams
同CHANGELOGより
参考: 週刊Railsウォッチ20230328: PostgreSQLのadd_index
でinclude
とwhere
を両方使えるようにする
🔗 ActiveRecord::Relation#none?
/#any?
/#one?
: support pattern arg by georgeclaghorn · Pull Request #46728 · rails/rails
ActiveRecord::Relation
’の以下のメソッドに、同等のEnumerable
により近い形でマッチするパターン引数をオプションで渡せるようになった。
#any?
#none?
#one?
George Claghorn
同CHANGELOGより
# 以下の2つは同等
products.any?(MediaBlock)
products.any? { |product| MediaBlock === product }
参考: 週刊Railsウォッチ20230125: ActiveRecord::Relation
の#none?
、#any?
、#one?
でEnumerable
と同様のパターン引数を渡せるようになった
🔗 Add ActiveRecord::Base::normalizes
by jonathanhefner · Pull Request #43945 · rails/rails
属性の正規化を宣言する
ActiveRecord::Base.normalizes
を追加。属性の正規化は、属性の代入または更新時に適用され、正規化された値はデータベースに永続化される。また、この正規化はクエリメソッドの対応するキーワード引数にも適用されるので、正規化されていない値でレコードをクエリできるようになる。
例:
class User < ActiveRecord::Base normalizes :email, with: -> email { email.strip.downcase } normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") } end user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COMn") user.email # => "cruise-control@example.com" user = User.find_by(email: "tCRUISE-CONTROL@EXAMPLE.COM ") user.email # => "cruise-control@example.com" user.email_before_type_cast # => "cruise-control@example.com" User.where(email: "tCRUISE-CONTROL@EXAMPLE.COM ").count # => 1 User.where(["email = ?", "tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0 User.exists?(email: "tCRUISE-CONTROL@EXAMPLE.COM ") # => true User.exists?(["email = ?", "tCRUISE-CONTROL@EXAMPLE.COM "]) # => false User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"
Jonathan Hefner
同CHANGELOGより
🔗 Hide changes to before_committed!
behaviour behind config by adrianna-chang-shopify · Pull Request #46739 · rails/rails
before_committed!
コールバックの振る舞いの変更をコンフィグで戻せるようになった。#46525で
before_committed!
コールバックの動作が変更され、トランザクションに登録されたすべてのレコードでコールバックが実行されるようになった。この振る舞いを、config.active_record.before_committed_on_all_records
という設定オプションで制御できるようになった(Rails 7.1ではデフォルトで有効)。Adrianna Chang
同CHANGELOGより
参考: 週刊Railsウォッチ20221206: before_committed!
コールバックをレコードの直近のコピーに対して実行するよう修正
参考: config.active_record.before_committed_on_all_records
-- Rails アプリケーションを設定する - Railsガイド
🔗 Query Logs: namespaced_controller
tag should match controller
format by ghiculescu · Pull Request #46641 · rails/rails
クエリログの
namespaced_controller
タグがコントローラの名前空間フォーマットとマッチするよう修正。たとえば
NameSpaced::UsersController
で処理されたリクエストは以下のようにログ出力されるようになった。:controller # "users" :namespaced_controller # "name_spaced/users"
Alex Ghiculescu
同CHANGELOGより
参考: Rails API ActiveRecord::QueryLogs
参考: config.active_record.query_log_tags
-- Rails アプリケーションを設定する - Railsガイド
🔗 Fix: ActiveRecord::Calculations#ids
returns duplicate ids by joshuay03 · Pull Request #46503 · rails/rails
ActiveRecord::Calculations
の#ids
が一意のidリストだけを返すよう修正。
ActiveRecord::Calculations#ids
が更新され、eager_load
、preload
、includes
でベースモデルの一意のidリストだけを返すようになった。Post.find_by(id: 1).comments.count # => 5 Post.includes(:comments).where(id: 1).pluck(:id) # => [1, 1, 1, 1, 1] Post.includes(:comments).where(id: 1).ids # => [1]
Joshua Young
同CHANGELOGより
参考: 週刊Railsウォッチ20221220: ActiveRecord::Calculations#ids
が返すidが重複する問題を修正
🔗 Don't use lower() for citext columns by pirj · Pull Request #46592 · rails/rails
PostgreSQLの
citext
カラムでは大文字小文字を区別しないクエリにlower()
を追加しないよう修正。従来はuniquenessバリデーションなどで
case_sensitive: false
を指定したときのクエリにlower()
が追加されていた。
しかし、lower()
が定義されていないインデックスに対してこれを行うとインデックスが効かなくなることが見落とされていた。Phil Pirozhkov
同CHANGELOGより
参考: PostgreSQL 15ドキュメント 9.4. 文字列関数と演算子
参考: PostgreSQL 15ドキュメント F.10. citext
参考: 週刊Railsウォッチ20221213: PostgreSQLのcitext
型カラムの検索時にlower()
を使わないようにした
🔗 Extract #sync_timezone_changes
method in AbstractMysqlAdapter by adrianna-chang-shopify · Pull Request #46604 · rails/rails
AbstractMysqlAdapter
の#sync_timezone_changes
メソッドをMySQL::DatabaseStatements
に移動した。
これにより、サブクラスで#raw_execute
をオーバーライドせずにデータベースのタイムゾーン変更を同期できるようになった。Adrianna Chang, Paarth Madan
同CHANGELOGより
🔗 Do not write additional new lines when dumping sql migration versions by mishaschwartz · Pull Request #46454 · rails/rails
マイグレーションのSQLダンプでバージョン番号に余分な行が追加されていたのを修正。
この変更によって
insert_versions_sql
関数が修正され、現在のマイグレーションバージョン番号を含む挿入文字列の末尾に余分な改行文字が2つ含まれないようになる。Misha Schwartz
同CHANGELOGより
🔗 Fix composed_of freezing by gregnavis · Pull Request #46377 · rails/rails
composed_of
の値のfreeze
やdup
を修正。従来のコンポジション値は、混乱を招く2通りの振る舞いを示していた。
- コンポジション値を読み取るときは値が
freeze
されない。このため、背後のデータベースカラムとの同期がずれてしまう。- コンポジション値を書き込むときは引数が
freeze
される。これによって呼び出し側が混乱する可能性がある。修正後、データベースカラムに基づいてインスタンス化されたコンポジション値は
freeze
されるようになった(問題1の修正)。代入したコンポジション値はdup
されるようになり、dup
したものをfreeze
するようになった(問題2の修正)。Greg Navis
同CHANGELOGより
参考: Rails API ActiveRecord::Aggregations::ClassMethods
🔗 Fix incorrect caching of case-insensitivity · rails/rails@b39050e
大文字小文字を区別しないカラムでキャッシュが効かなかったのを修正。
カラムが大文字小文字を区別しない比較が可能かどうかをチェックすることで余分なクエリを発行しないよう修正した。
Phil Pirozhkov
同CHANGELOGより
🔗 option to disable all methods that ActiveRecord.enum generates by alfie-max · Pull Request #46490 · rails/rails
ActiveRecord.enum
によるメソッド生成をinstance_methods: false
オプションで無効にできるようになった。Alfred Dominic
同CHANGELOGより
参考: Rails 7.1に入る主要な機能まとめ(3) -- ActiveRecord#enum
のメソッド生成を無効にするオプションが追加された
🔗 Avoid validating belongs_to
association if it has not changed by fatkodima · Pull Request #46522 · rails/rails
belongs_to
関連付けで変更が生じていない場合のバリデーションを回避するようになった。従来のActive Recordは、レコード更新時に
belongs_to
関連付けで(存在が必須と設定されている場合に)存在チェックの追加クエリを実行していたが、属性が変更されていない場合でも実行していた。修正後は、
belongs_to
に関連するカラムだけが存在チェックされるようになった。ただしこの方法では孤立レコードができてしまう可能性があるので、この問題を回避するには外部キーを使う必要がある。この振る舞いは、以下のコンフィグで制御できる。
config.active_record.belongs_to_required_validates_foreign_key = false
この設定は
config.load_defaults 7.1
ではデフォルトでfalse
に設定される。fatkodima
同CHANGELOGより
参考: config.active_record.belongs_to_required_validates_foreign_key
-- Rails アプリケーションを設定する - Railsガイド
参考: Rails 7.1に入る主要な機能まとめ(3) -- 属性が変更されていないbelongs_to
関連付けのバリデーションを回避するようになった
🔗 Allow resetting singular associations by georgeclaghorn · Pull Request #46165 · rails/rails
has_one
関連付けとbelongs_to
関連付けで、オーナーモデルにreset_関連付け名
が定義されるようになった。このメソッドは、キャッシュされた関連付けレコードがあればアンロードし、次回のアクセスでデータベースから読み込むようになる。
George Claghorn
同CHANGELOGより
参考: Rails 7.1に入る主要な機能まとめ(3) -- 単数形の関連付けをリセットできるようになった
🔗 Permit YAML classes and unsafe load per attribute · rails/rails@e313fc5
serialize
にyaml
オプションが追加され、permitted_classes
(safe_load
用)やunsafe_load
を属性単位で設定できるようになった。Carlos Palhares
同CHANGELOGより
# 同APIドキュメントより
class User < ActiveRecord::Base
serialize :preferences, yaml: { permitted_classes: [Symbol, Time] }
end
🔗 Add a build persistence method by seand7565 · Pull Request #45696 · rails/rails
永続化を行う
build
メソッドを追加。
new
のラッパーを提供し、関連付けのbuild
メソッドと同じ記法で、create
と同様にハッシュの配列から複数のレコードを作成する機能を提供する。Sean Denny
同CHANGELOGより
# 同APIドキュメントより
# 単一のオブジェクトをビルド
User.build(first_name: 'Jamie')
# 新規オブジェクトの配列を渡してビルド
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
# 単一のオブジェクトをビルドし、ブロックで他の属性を設定
User.build(first_name: 'Jamie') do |u|
u.is_admin = false
end
# 新規オブジェクトの配列を渡してビルド:(ブロックはオブジェクトごとに設定される)
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
u.is_admin = false
end
参考: 週刊Railsウォッチ20221206: build
メソッドにハッシュの配列を渡すことで複数のオブジェクトをまとめてbuild
できるようになった
🔗 Raise on assignment to readonly attributes by hmcguire-shopify · Pull Request #46105 · rails/rails
attr_readonly
で生成した属性に代入するとエラーを発生するようになった。class Post < ActiveRecord::Base attr_readonly :content end Post.create!(content: "cannot be updated") post.content # "cannot be updated" post.content = "something else" # => ActiveRecord::ReadonlyAttributeError
従来はデータベースに書き込まずに代入に成功してしまい、エラーを発生しなかった。
この振る舞いは以下のコンフィグで制御できる。
config.active_record.raise_on_assign_to_attr_readonly = true
config.load_defaults 7.1
ではこの振る舞いがデフォルトで有効になる。Alex Ghiculescu, Hartley McGuire
同CHANGELOGより
参考: config.active_record.raise_on_assign_to_attr_readonly
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20221129: readonlyの属性に代入すると`ActiveRecord::ReadonlyAttributeError`を発生するようになった
🔗 Allow unscoping of preload and eager_load associations by dmorehouse · Pull Request #45147 · rails/rails
unscope
で関連付けのpreload
やeager_load
も指定できるようになった。
includes
やjoins
などと同様に、unscope
で関連付けのpreload
やeager_load
を行う機能が追加された。サポートされているunscope
可能なスコープの完全なリストについては、ActiveRecord::QueryMethods::VALID_UNSCOPING_VALUES
を参照。query.unscope(:eager_load, :preload).group(:id).select(:id)
David Morehouse
同CHANGELOGより
参考: 週刊Railsウォッチ20221129: 関連付けのpreload
やeager_load
をunscope
できるようになった
🔗 Add filtering of encrypted attributes in #inspect by skipkayhil · Pull Request #46453 · rails/rails
inspect
で暗号化済み属性をフィルタで自動的に除外するようになった。この機能はデフォルトで有効になるが、以下のコンフィグを設定することで無効にできる。
config.active_record.encryption.add_to_filter_parameters = false
Hartley McGuire
同CHANGELOGより
この機能により、暗号化済み属性は自動的にログからも除外されるようになります。
参考: config.active_record.add_to_filter_parameters
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20221129: #inspect
実行時に暗号化済み属性を自動的にフィルタで除外する機能が追加された
🔗 Clear locking column on #dup by shouichi · Pull Request #46243 · rails/rails
レコードを
#dup
したときにlocking_column
を解除するようになった。この変更により、idやタイムスタンプなどの
locking_column
が複製されない問題が修正される。car = Car.create! car.touch car.lock_version #=> 1 car.dup.lock_version #=> 0
Shouichi Kamiya, Seonggi Yang, Ryohei UEDA
同CHANGELOGより
参考: Rails API locking_column
-- ActiveRecord::Locking::Optimistic::ClassMethods
🔗 Invalidate transaction as early as possible by nvasilevski · Pull Request #46367 · rails/rails
トランザクションを可能な限り早期に無効化するようになった。
TransactionRollbackError
例外をrescue
した後、トランザクションをフローの早い段階で無効化し、フレームワークがROLLBACK
ステートメントの発行をスキップするケースを増やす。
これが影響するのは、savepoint_errors_invalidate_transactions?
にtrue
を設定しているアダプタのみであり、現時点ではmysql2
アダプタにのみ影響する。Nikita Vasilevsky
同CHANGELOGより
参考: Rails API savepoint_errors_invalidate_transactions?
-- ActiveRecord::ConnectionAdapters::Mysql2Adapter
🔗 Allow specifying columns to use in ActiveRecord::Base object queries by nvasilevski · Pull Request #46331 · rails/rails
ActiveRecord::Base
オブジェクトが発行するSQLクエリで複数カラムのリストを設定できるようになった。複数カラムをリストとして設定可能になったことで、
ActiveRecord::Base
オブジェクトを更新/削除/リロードしたときのSQLクエリ句のビルドで使われるようになった。class Developer < ActiveRecord::Base query_constraints :company_id, :id end developer = Developer.first.update(name: "Bob") # => UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
Nikita Vasilevsky
同CHANGELOGより
参考: 週刊Railsウォッチ20221115: ActiveRecord::Base
オブジェクトのクエリでカラムのリストを指定可能になった
🔗 Adds validate to foreign keys and check constraints in schema.rb by TAGraves · Pull Request #46339 · rails/rails
(PostgreSQL)schema.rbの外部キーやCHECK制約に
validate
を追加するようになった。従来は、外部キーやCHECK制約の追加に
validate: false
を指定したかどうかがschema.rbに記録されていなかったため、データベースをスキーマからリストアすると外部キーやCHECK制約が誤ってバリデーションされる可能性があった。Tommy Graves
同CHANGELOGより
参考: 週刊Railsウォッチ20221115: schema.rbの外部キーやCHECK制約にvalidate: false
を追加するようになった(PostgreSQL)
🔗 Allow adapter #execute
methods to take allow_retry
option by adrianna-chang-shopify · Pull Request #46273 · rails/rails
データベースアダプタの
#execute
メソッドにallow_retry
オプションを渡せるようになった。このオプションを
true
に設定するとSQLステートメントがリトライされるようになる。リトライは、リトライ回数がデータベース設定のconnection_retries
値に達するまで、またはコネクション関連のエラーが発生するまで行われる。Adrianna Chang
同CHANGELOGより
参考: 週刊Railsウォッチ20221115: DBアダプタの#execute
メソッドにallow_retry
オプションを渡せるようになった
🔗 Don't trigger after_commit :destroy
callback again on destroy if record previously was destroyed by bensheldon · Pull Request #46197 · rails/rails
データベース行が削除済みの場合にのみ
after_commit :destroy
がトリガーされるようになった。これにより、同じレコードに対して
destroy
が複数回呼び出された場合にafter_commit :destroy
コールバックが複数回トリガーされるのを防止する。Ben Sheldon
同CHANGELOGより
参考: 週刊Railsウォッチ20221101: 同一レコードでafter_commit :destroy
の重複トリガーを解消
🔗 Fix ciphertext_for
for yet-to-be-encrypted values by jonathanhefner · Pull Request #46284 · rails/rails
ciphertext_for
が返す値が暗号化されないバグを修正。従来の
ciphertext_for
は、永続化されていないレコードなどから暗号化されていない平文を返していた。Post.encrypts :body post = Post.create!(body: "Hello") post.ciphertext_for(:body) # => "{"p":"abc..." post.body = "World" post.ciphertext_for(:body) # => "World"
修正後の
ciphertext_for
は、暗号化属性から常に暗号化済みテキストを返すようになった。Post.encrypts :body post = Post.create!(body: "Hello") post.ciphertext_for(:body) # => "{"p":"abc..." post.body = "World" post.ciphertext_for(:body) # => "{"p":"xyz..."
Jonathan Hefner
同CHANGELOGより
参考: 週刊Railsウォッチ20221101: ciphertext_for
が暗号化前の値を返す問題を修正
🔗 Fix a bug where using groups and counts with long table names would return incorrect results. by Dooor · Pull Request #46287 · rails/rails
テーブル名が長い場合に
group
やcount
が誤った値を返すバグを修正。Shota Toguchi, Yusaku Ono
同CHANGELOGより
この修正は、Rails 7.0.5でリリース済みです。
🔗 Fix encryption of column default values by jonathanhefner · Pull Request #46281 · rails/rails
カラムのデフォルト値の暗号化を修正。
従来は、カラムのデフォルト値が設定されている暗号化属性がレコード作成時に暗号化されているように見えていたが、実際には暗号化されていなかった。
Book.encrypts :name book = Book.create! book.name # => "<untitled>" book.name_before_type_cast # => "{"p":"abc..." book.reload.name_before_type_cast # => "<untitled>"
修正後は、カラムのデフォルト値を設定した暗号化属性が暗号化されるようになった。
Book.encrypts :name book = Book.create! book.name # => "<untitled>" book.name_before_type_cast # => "{"p":"abc..." book.reload.name_before_type_cast # => "{"p":"abc..."
Jonathan Hefner
同CHANGELOGより
🔗 Deprecate delegation to connection handler from Base by eileencodes · Pull Request #46274 · rails/rails
Base
からconnection_handler
への委譲を非推奨化。以下の呼び出しが非推奨化された。
Base.clear_all_connections!
Base.clear_active_connections!
Base.clear_reloadable_connections!
Base.flush_idle_connections!
今後これらのメソッドはコネクションハンドラで直接呼び出すこと。
Base
からconnection_handler
への委譲は今後のRailsで削除される予定。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API ActiveRecord::ConnectionAdapters::ConnectionHandler
🔗 Allow ActiveRecord::QueryMethods#reselect to accept a hash by sampatbadhe · Pull Request #46253 · rails/rails
ActiveRecord::QueryMethods#reselect
にもActiveRecord::QueryMethods#select
と同様にハッシュ値を渡せるようになった。Sampat Badhe
同CHANGELOGより
# 同PRより(以下の2つは同じ)
Post.select(:title, posts: { title: :post_title })
Post.select(:title, :body).reselect(:title, posts: { title: :post_title })
参考: 週刊Railsウォッチ20221101: ActiveRecord::QueryMethods#reselect
にもカラムやエイリアスを含むハッシュを渡せるようになった
🔗 Validate options when managing columns and tables in migration by tgxworld · Pull Request #46178 · rails/rails
マイグレーションのカラム/テーブル管理メソッドに渡されるオプションが有効かどうかをバリデーションするようになった。
create_table
やadd_column
などのマイグレーション用メソッドに無効なオプションを渡すと、従来は単に無視されていたが、修正後はエラーを発生するようになった。
オプションのバリデーションは、新規作成されたマイグレーションに対してのみ適用される。Guo Xiang Tan, George Wambold
同CHANGELOGより
参考: 週刊Railsウォッチ20221025: 新規マイグレーションのカラム/テーブル管理で無効なオプションが指定されるとraiseするようになった
🔗 Add ability to set the tags_format
for QueryLogs
by iheanyi · Pull Request #45081 · rails/rails
QueryLogs
のタグフォーマットにデフォルトでSQLCommenter形式が使われるようになった。
詳しくは#46179を参照。
QueryLogs
でSQLCommenter形式のタグを無効にするには、config.active_record.query_log_tags_format = :legacy
を設定する。
デフォルトでは:sqlcommenter
が設定される。Modulitos and Iheanyi
同CHANGELOGより
参考: Rails API ActiveRecord::QueryLogs
参考: config.active_record.query_log_tags_format
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20221018: QueryLogsでtags_format
オプションを指定可能になった
🔗 Facilitate use of any regular ERB in database.yml by eikes · Pull Request #46134 · rails/rails
rakeタスク作成時にdatabase.ymlで任意のERBを書けるようになった。
環境設定にアクセスする場合でも
database.yml
に任意のERBを書けるようになった。
config.active_record.suppress_multiple_database_warning
設定は非推奨化された。Eike Send
同CHANGELOGより
参考: RailsガイドのRails アプリケーションを設定するには、このconfig.active_record.suppress_multiple_database_warning
はこれまで記載されていません。
参考: 週刊Railsウォッチ20221018: database.ymlのYAMLキーに任意のERBを書けるようになった
🔗 Add table name to error for duplicate column definitions by p8 · Pull Request #46117 · rails/rails
カラム定義が重複していた場合のエラーメッセージにテーブル名も出力されるようになった。
マイグレーションでテーブルのカラム定義が重複している場合に、問題が生じたテーブル名を含むエラーメッセージが表示される。
Petrik de Heus
同CHANGELOGより
# 同PRより: テーブル名'testings'が出力される
you can't define an already defined column 'testing_column' on 'testings'.
🔗 Fix erroneous nil default precision on virtual datetime columns by sambostock · Pull Request #46110 · rails/rails
仮想の
datetime
カラムがデフォルトでprecision: nil
になっていたのを修正。この修正の前は、仮想の
datetime
カラムのデフォルト精度が通常のdatetime
カラムのデフォルト精度と同じになっておらず、以下の2つが誤って同等になっていた。t.virtual :name, type: datetime, as: "expression" t.virtual :name, type: datetime, precision: nil, as: "expression"
この変更では、デフォルト精度の探索が修正され、
datetime
のデフォルト精度が仮想カラムでも通常カラムでも一致するようになった。Sam Bostock
同CHANGELOGより
この修正は、Rails 7.0.5でリリース済みです。
🔗 Use #with_raw_connection
in #quote_string
to retry connection errors by adrianna-chang-shopify · Pull Request #46108 · rails/rails
#quote_string
で#with_raw_connection
のコネクションを使うようになった。これにより、
#with_raw_connection
が提供する再接続・リトライロジックによって#quote_string
がラップされるようになる。Adrianna Chang
同CHANGELOGより
参考: Rails API quote_string
-- ActiveRecord::ConnectionAdapters::Quoting
🔗 Add expires_at
option to signed_id
· rails/rails@364939c
失効日時を指定する
expires_at
オプションをsigned_id
に追加。Shouichi Kamiya
同CHANGELOGより
# 同PRより
Account.find_signed(@account.signed_id(expires_at: 1.minute.from_now)
参考: Rails API signed_id
-- ActiveRecord::SignedId
🔗 Take into account timeout limit when retrying queries by adrianna-chang-shopify · Pull Request #46046 · rails/rails
クエリのリトライ期間に上限を設定できるようになった。
#44576と#44591で行われた作業を基に、データベースコネクションの自動再接続ロジックを拡張してタイムアウト制限を考慮するようになった。クエリが最初に試行されてから一定時間経過すると、クエリは再試行されなくなる。この値にはデフォルトでは
nil
が設定されている(経過時間に関係なくすべての再試行可能なクエリが再試行される)。これはデータベース設定のretry_deadline
オプションで変更可能。Adrianna Chang
同CHANGELOGより
# 同PRより
development:
adapter: mysql2
retry_deadline: 5 # 5秒経過したらリトライを停止
🔗 Dup and freeze complex types when making query attributes by tenderlove · Pull Request #46048 · rails/rails
クエリキャッシュが誤った値を返すことがあるバグを修正。
#46044を参照。
Aaron Patterson
同CHANGELOGより
🔗 Add ssl-mode option to dbconsole command and MySQLDatabaseTasks by p8 · Pull Request #46008 · rails/rails
MySQLDatabaseTasks
でMySQLのSSLモードオプションをサポート。データベースサーバーの識別情報を検証するには、
--ssl-mode
オプションにVERIFY_CA
またはVERIFY_IDENTITY
を設定する必要がある。従来、データベース作成やstructureダンプなどのMySQLデータベースタスクでこのオプションが無視されていた。Petrik de Heus
同CHANGELOGより
参考: 週刊Railsウォッチ20221011: dbconsoleコマンドとMySQLDatabaseTasksに--ssl-mode
オプションを追加
🔗 Move InternalMetadata to an independent object by eileencodes · Pull Request #45982 · rails/rails
ActiveRecord::InternalMetadata
を別オブジェクトに移動。
ActiveRecord::InternalMetadata
はActiveRecord::Base
を継承しなくなり、connection
を渡して初期化する独立したオブジェクトになった。
このクラスはprivateであり、アプリケーションから直接使うべきではない。スキーママイグレーションのテーブルとやりとりする必要がある場合は、ActiveRecord::Base.connection.schema_migration
のように直接コネクションにアクセスすること。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API ActiveRecord::InternalMetadata
🔗 Deprecate quoting ActiveSupport::Duration as an integer (#44341) by aramgre · Pull Request #44438 · rails/rails
ActiveSupport::Duration
を整数値として式展開することを非推奨化。SQL文字列テンプレート内で
ActiveSupport::Duration
を式展開にバインドするパラメータとして利用することが非推奨化された。
この非推奨警告表示を回避するには、明示的にDuration
をより具体的なデータベース型に変換すること。
たとえば、Duration
を秒単位の整数値として利用したい場合は、以下のように書くこと。Record.where("duration = ?", 1.hour.to_i)
Duration
をISO 8601形式の文字列として使いたい場合は、以下のように書くこと。Record.where("duration = ?", 1.hour.iso8601)
Aram Greenman
同CHANGELOGより
参考: この変更には後方互換用のコンフィグはありません(#44438コメント)。
🔗 improve "in_order_of" to allow string column name by igorkasyanchuk · Pull Request #45971 · rails/rails
QueryMethods
の#in_order_of
による並べ替えが、カラム名が文字列の場合にも使えるようになった。Post.in_order_of("id", [4,2,3,1]).to_a Post.joins(:author).in_order_of("authors.name", ["Bob", "Anna", "John"]).to_a
Igor Kasyanchuk
同CHANGELOGより
参考: Rails API in_order_of
-- ActiveRecord::QueryMethods
🔗 Move SchemaMigration to an independent object by eileencodes · Pull Request #45908 · rails/rails
ActiveRecord::SchemaMigration
を別オブジェクトに移動。
ActiveRecord::SchemaMigration
はActiveRecord::Base
を継承しなくなり、connection
を渡して初期化する独立したオブジェクトになった。
このクラスはprivateであり、アプリケーションから直接使うべきではない。スキーママイグレーションのテーブルとやりとりする必要がある場合は、ActiveRecord::Base.connection.schema_migration
のように直接コネクションにアクセスすること。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API ActiveRecord::SchemaMigration
🔗 Make connection_pool_list take an explicit argument by eileencodes · Pull Request #45961 · rails/rails
all_connection_pools
を非推奨化し、connection_pool_list
にオプションを明示的に渡すようにした。#45924に続いて、
all_connection_pools
を非推奨化した。
connection_pool_list
には明示的にrole
引数を渡すようになった。この引数に:all
を渡すことで、アプリケーションで新しい振る舞いを選択できるようになる。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API connection_pool_list
-- ActiveRecord::ConnectionAdapters::ConnectionHandler
🔗 Fix bug in connection handler methods using all pools by eileencodes · Pull Request #45924 · rails/rails
コネクションハンドラのメソッドがすべてのコネクションプールで動作するよう修正。
以下のメソッドが、デフォルトですべてのコネクションプールで動作するようになった。
active_connections?
clear_active_connections!
clear_reloadable_connections!
clear_all_connections!
flush_idle_connections!
従来は、ロールを指定しない場合にデフォルトで
current_role
ロールまたは:writing
ロールが使われていた。Eileen M. Uchitelle
同CHANGELOGより
参考: 週刊Railsウォッチ20221003: コネクションハンドラメソッドのバグを修正
🔗 Allow ActiveRecord::QueryMethods#select to accept a hash by alextrueman · Pull Request #45612 · rails/rails
ActiveRecord::QueryMethods
の#select
にハッシュ値を渡せるようになった。従来は、
select
でカラム定義やselect
のエイリアス定義を行うには生SQLまたはシンボルを渡すしかなかった。この変更によって、以下のように
hash
を引数として渡せるようになる。Post.joins(:comments).select(posts: [:id, :title, :created_at], comments: [:id, :body, :author_id]) #=> "SELECT "posts"."id", "posts"."title", "posts"."created_at", "comments"."id", "comments"."body", "comments"."author_id" # FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"" Post.joins(:comments).select(posts: { id: :post_id, title: :post_title }, comments: { id: :comment_id, body: :comment_body }) #=> "SELECT posts.id as post_id, posts.title as post_title, comments.id as comment_id, comments.body as comment_body # FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id""
Oleksandr Holubenko, Josef Šimánek, Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20220926: ActiveRecord::QueryMethods#select
にハッシュを渡せるようになった
🔗 Normalize virtual attributes on ActiveRecord::Persistence#becomes by intrip · Pull Request #42650 · rails/rails
ActiveRecord::Persistence
の#becomes
で仮想属性を使えるようになった。ソースクラスとターゲットクラスの属性セットが異なる場合は、ターゲットクラスの属性を追加する形で属性を適応させるようになる。
class Person < ApplicationRecord end class WebUser < Person attribute :is_admin, :boolean after_initialize :set_admin def set_admin write_attribute(:is_admin, email =~ /@ourcompany.com$/) end end person = Person.find_by(email: "email@ourcompany.com") person.respond_to? :is_admin # => false person.becomes(WebUser).is_admin? # => true
Jacopo Beschi, Sampson Crowley
同CHANGELOGより
参考: Rails API becomes
-- ActiveRecord::Persistence
参考: 週刊Railsウォッチ20220920: ActiveRecord::Persistence#becomes
をvirtual attributeに適応させる
🔗 Fix ActiveRecord::QueryMethods#in_order_of
to work with nils by fatkodima · Pull Request #45670 · rails/rails
Enumerable#
のin_order_of
の振る舞いに合わせるため、ActiveRecord::QueryMethods
の#in_order_of
がnil
を扱えるよう修正。たとえば、
Post.in_order_of(:title, [nil, "foo"])
でタイトルがnil
のpostsも含まれるようになる。これはPost.all.to_a.in_order_of(:title, [nil, "foo"])
の振る舞いと同じ。fatkodima
同CHANGELOGより
参考: Rails API in_order_of
-- ActiveRecord::QueryMethods
参考: Rails API in_order_of
-- Enumerable
参考: 週刊Railsウォッチ20220905: ActiveRecord::QueryMethods#in_order_of
のソート対象の値がnil
でも動作するよう修正
🔗 Optimize add_timestamps to use a single SQL statement when supported by ilianah · Pull Request #45723 · rails/rails
add_timestamps
が発行するSQLステートメントが1つだけになるよう最適化。add_timestamps :my_table
上によって以下のSQLが生成されるようになる。
ALTER TABLE "my_table" ADD COLUMN "created_at" datetime(6) NOT NULL, ADD COLUMN "updated_at" datetime(6) NOT NULL
Iliana Hadzhiatanasova
同CHANGELOGより
参考: §3.9 changeメソッドを使う -- Active Record マイグレーション - Railsガイド
🔗 Add drop_enum
command for Postgres by ghiculescu · Pull Request #45735 · rails/rails
マイグレーションコマンドに
drop_enum
を追加(PostgreSQLのみ)。これは
create_enum
と逆の動作。enumを削除する前には、そのenumに依存しているカラムを必ず削除しておくこと。Alex Ghiculescu
同CHANGELOGより
🔗 Add support for if_exists
option when removing a check constraint · rails/rails@25f97a6
CHECK制約の削除で
if_exists
をサポート。
remove_check_constraint
メソッドにif_exists
オプションを渡せるようになった。if_exists: true
を設定すると、そのCHECK制約が存在しない場合にエラーを発生しなくなる。Margaret Parsa and Aditya Bhutani
同CHANGELOGより
参考: §3.9 changeメソッドを使う -- Active Record マイグレーション - Railsガイド
参考: 週刊Railsウォッチ20220822: CHECK制約の削除でif_exists
オプションが利用可能になる
🔗 find_or_create_by: handle race condition by finding again by casperisfine · Pull Request #45720 · rails/rails
find_or_create_by
でRecordNotUnique
が発生した場合はfind
をリトライするようになった。
find_or_create_by
は本質的に競合がつきものなので、適切なunique制約が設定されているかどうかで「重複レコードを作成する」か「ActiveRecord::RecordNotUnique
で失敗する」かが決まる。このユースケース向けに
create_or_find_by
が導入されたが、レコードが既に存在する可能性が非常に高い場合は、INSERTはSELECTよりも多くのデータ送信が必要になり、データベース側の作業も増加するため、効率がかなり悪くなる。また、データベースによっては、主キーのインクリメント(望ましくない)が消費される可能性もある。そのため、レコードが既に存在する可能性が非常に高いユースケースでは、
create
がActiveRecord::RecordNotUnique
で失敗した場合はfind
を再試行することで競合が発生しないようにできる。これはテーブルで適切なunique制約が設定されていることが前提となる。さもないと、find_or_create_by
で引き続き重複レコードが発生する。Jean Boussier, Alex Kitchens
同CHANGELOGより
参考: §19.1 find_or_create_by
-- Active Record クエリインターフェイス - Railsガイド
参考: Rails API create_or_find_by
-- ActiveRecord::Relation
参考: 週刊Railsウォッチ20220822: find_or_create_by
でRecordNotUnique
エラーの場合にfind
をリトライするようになった
🔗 Simplify adapter construction; defer connect until first use by matthewd · Pull Request #44591 · rails/rails
Active Recordのデータベースアダプタに、よりシンプルなコンストラクタAPIが導入された。
従来は、データベースアダプタが再接続をサポートするために新しい
raw_connection
のビルド方法を知っている必要があったが、最初の確立済みコネクションを渡されることも期待されていた。改修後は、アダプタのインスタンスを手動で作成する場合は、コンフィグ用ハッシュを1個渡すだけで、必要に応じて実際の接続が確立するようになった。
Matthew Draper
同CHANGELOGより
可能な場合は、DBプールのチェックアウト中に
SELECT 1
による余分なコネクションバリデーション用クエリを避けるようになった。リクエスト中の最初のクエリが冪等であることがわかっている場合は、これを用いてコネクションを直接バリデーションできるので、ネットワークのやりとりが削減される。
Matthew Draper
同CHANGELOGより
🔗 Defer verification of database connections by matthewd · Pull Request #44576 · rails/rails
コネクションが切断された場合、安全であればリクエストの途中でもデータベースコネクションを自動で再接続するようになった。
冪等であることがわかっているクエリを実行しようとしてエラーが発生した場合、かつトランザクション内でない場合は、直ちにデータベースサーバーに再接続しても安全である。今後はこれがデフォルトの振る舞いになる。
新しいデフォルトの振る舞いは常に安全でなければならない。この振る舞いをサポートするため、どのクエリを冪等と認識するかについては保守的なアプローチを取っている。ただし、この振る舞いは、データベースコネクションの
connection_retries
オプションに0
を設定することで無効にできる。Matthew Draper
同CHANGELOGより
参考: Rails API connection_retries
-- ActiveRecord::ConnectionAdapters::AbstractAdapter
🔗 Avoid removing a PostgreSQL extension when there are dependent objects by fatkodima · Pull Request #45474 · rails/rails
PostgreSQL拡張に依存しているオブジェクトが存在する場合は、その拡張の削除を回避するようになった。
従来は、拡張を削除すると依存オブジェクトも暗黙で削除されていた。
改修後は、このような削除を行うとエラーを発生するようになった。マイグレーションで以下のように拡張を強制削除することも可能。
disable_extension :citext, force: :cascade
修正: #29091
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20220801: PostgreSQL拡張機能に依存するオブジェクトがある場合は削除しないようになった
🔗 Accept nested functions in Dangerous Query Methods by siegfault · Pull Request #44010 · rails/rails
ネストしたSQL関数を安全なSQL文字列として扱えるようになった。
Michael Siegfried
同CHANGELOGより
# 同PRより
Post.pluck(Arel.sql("length(trim(title))"))
参考: 週刊Railsウォッチ20220725: ネストしたSQL関数を安全なSQL文字として許容する
🔗Defer constant loading of ActiveRecord::DestroyAssociationAsyncJob
via a String instead of a class constant by bensheldon · Pull Request #45476 · rails/rails
destroy_association_async_job=
に設定するクラス(定数)を、クラス名の文字列でも設定できるようになった。
ActiveRecord::Base
とActiveJob::Base
の間のオートローディングを先延ばしするようにし、ActiveRecord::DestroyAssociationAsyncJob
の設定をActive JobからActive Recordに移動した。
ActiveRecord::ActiveJobRequiredError
は非推奨化された。
これにより、ジョブクラスが読み込み不能な場合はNameError
が発生するようになった。また、関連付けで
dependent: :destroy_async
が宣言され、かつジョブクラスが未設定の場合はActiveRecord::ConfigurationError
が発生するようになった。Ben Sheldon
同CHANGELOGより
参考: Rails API destroy_association_async_job
-- ActiveRecord::Core
参考: config.active_record.destroy_association_async_job
-- Rails アプリケーションを設定する - Railsガイド
🔗 ActiveRecord::Store encode store as a regular Hash by casperisfine · Pull Request #45591 · rails/rails
ActiveRecord::Store
におけるハッシュのシリアライズを通常のハッシュとして行うよう修正。従来は
ActiveSupport::HashWithIndifferentAccess
としてシリアライズしていたが、これは無駄が多く、YAML safe_load
で問題を生じる。Jean Boussier
同CHANGELOGより
この修正は、Rails 7.0.4と6.1.7でリリース済みです。
🔗 Add timestamptz
as a time zone aware type for PostgreSQL by ghiculescu · Pull Request #44601 · rails/rails
PostgreSQLのタイムゾーン対応型
timestamptz
を追加。データベース内で
timestamp with time zone
値を正しく解析するにはこの型が必要。これを使いたくない場合は、イニシャライザに以下を追加することで無効にできる。
ActiveRecord::Base.time_zone_aware_types -= [:timestamptz]
Alex Ghiculescu
同CHANGELOGより
この修正は、Rails 7.0.4でリリース済みです。
🔗 Add ActiveRecord::Base::generates_token_for
by jonathanhefner · Pull Request #44189 · rails/rails
ActiveRecord::Base.generates_token_for
APIを新たに追加。現在の
signed_id
は、パスワードのリセットなどでトークンを生成する役割を担当している。しかしsigned_id
にはレコードのステートを反映できないので、トークンを1回だけ使う場合は、少なくとも期限切れまでデータベースでトラッキングしなければならなくなる。
generates_token_for
を使うことで、トークンにレコードのデータを埋め込めるようになる。このトークンを用いてレコードを取得すると、トークンのデータと現在のレコードのデータが比較される。両者が一致しない場合、トークンは無効と見なされるため、期限切れした場合と同じ扱いになる。例:
class User < ActiveRecord::Base has_secure_password generates_token_for :password_reset, expires_in: 15.minutes do # `password_salt`(`has_secure_password`で定義される)は、 # そのパスワードのsaltを返す。パスワードが変更されるとsaltも変更されるので、 # パスワードが変更されるとこのトークンは無効になる。 BCrypt::Password.new(password_digest).salt[-10..] end end user = User.first token = user.generate_token_for(:password_reset) User.find_by_token_for(:password_reset, token) # => user user.update!(password: "new password") User.find_by_token_for(:password_reset, token) # => nil
Jonathan Hefner
同CHANGELOGより
参考: Rails API generates_token_for
-- `ActiveRecord::TokenFor::ClassMethods
🔗 Optimize Active Record batching for whole table iterations by fatkodima · Pull Request #45414 · rails/rails
Active Recordのテーブル全体をイテレーションするバッチを最適化。
従来の
in_batches
では、全idを取得したうえでバッチごとにIN
ベースのクエリを構築していた。テーブル全体をイテレーションする場合、この方法では不要なidまで読み込まれてしまい、IN
クエリの項目数が増えて遅くなる。改修後は、テーブル全体のイテレーションでは範囲指定(
id >= x AND id <= y
)をデフォルトで使うようになり、イテレーションが数倍高速になる。たとえば、PostgreSQLで1000万件のレコードを持つテーブルでテストした場合のクエリ時間は253s
->30s
、更新は288s
->124s
、削除は268s
->83s
となった。このイテレーションをデフォルトで使うのはテーブル全体をイテレーションする場合に限られる。この振る舞いは、
use_ranges: false
オプションを渡すことで無効化できる。テーブル全体のイテレーションで、
archived_at: nil
のような条件だけを指定する場合(かつアーカイブ済みのレコードがごく一部しかない場合)、このアプローチを採用する意義がある。Project.where(archived_at: nil).in_batches(use_ranges: true) do |relation| # 何かする end
詳しくは#45414を参照。
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20220711: Active Recordのin_batches
でuse_ranges: true
を指定可能になった
🔗 Common Table Expression support added "out-of-the-box" by vlado · Pull Request #37944 · rails/rails
.with
クエリメソッドを追加。
CTE(Common Table Expression)を手軽に構築してActiveRecord::Relation
を得られるようになった。Post.with(posts_with_comments: Post.where("comments_count > ?", 0)) # => ActiveRecord::Relation # WITH posts_with_comments AS (SELECT * FROM posts WHERE (comments_count > 0)) SELECT * FROM posts
Vlado Cingel
同CHANGELOGより
参考: PostgreSQL 15ドキュメント 7.8. WITH問い合わせ(共通テーブル式)
参考: 週刊Railsウォッチ20220711: ActiveRecord::Relation
にCTEを利用できるwith
メソッドが追加
🔗 Only remove connection for an existing pool if the config is different by eileencodes · Pull Request #45450 · rails/rails
同一のコネクションプールが既に存在する場合は新しいコネクションを確立しないようになった。
従来は、既に確立済みのコネクションを持つクラスで
establish_connection
が呼び出されると、設定が同じかどうかに関係なく既存のコネクションが削除された。
改修後は、新しいコネクションと同じ値を持つコネクションプールが見つかった場合、新しいコネクションではなく既存のコネクションを返すようになった。アプリケーションのコードが、新しいコネクションが既存のコネクションと同一かどうかにかかわらず確立される振る舞いに依存している場合、振る舞いがわずかに変更されることになる。
古い振る舞いに戻したい場合は、新しいコネクションを確立する前にActiveRecord::Base#remove_connection
を呼び出す必要がある。設定を変えてestablish_connection
を呼び出す場合の振る舞いは、従来と同様になる。Eileen M. Uchitelle
同CHANGELOGより
参考: Rails API establish_connection
-- ActiveRecord::ConnectionHandling
🔗 Allow db:prepare
to load schema if database already exists but is empty; also dumps schema after migrations by bensheldon · Pull Request #45464 · rails/rails
db:prepare
タスクを更新。初期化されていないデータベースが存在する場合はスキーマを読み込み、残りのマイグレーションがあれば実行して、その後スキーマをダンプするように変更した。
Ben Sheldon
同CHANGELOGより
参考: 週刊Railsウォッチ20220719: 空のデータベースが存在していてもdb:prepare
でスキーマを読み込み可能にした
🔗 Fix supporting timezone awareness for tsrange
array columns. by morgoth · Pull Request #45348 · rails/rails
(PostgreSQLのみ)範囲型の
tsrange
カラムとtstzrange
カラムでタイムゾーンを認識するサポートを修正。# データベースのマイグレーション内 add_column :shops, :open_hours, :tsrange, array: true # アプリのコンフィグ内 ActiveRecord::Base.time_zone_aware_types += [:tsrange] # このコードのtimeがアプリのタイムゾーンに正しく変換されるようになる Shop.create!(open_hours: [Time.current..8.hour.from_now])
Wojciech Wnętrzak
同CHANGELOGより
この修正は、Rails 7.0.4でリリース済みです。
参考: Rails API ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods
参考: PostgreSQL 15ドキュメント 8.17. 範囲型
🔗 Introduce "Execution Strategy" object for Migrations by adrianna-chang-shopify · Pull Request #45324 · rails/rails
マイグレーションの実行にStrategyパターンを導入。
デフォルトでは、メソッドをコネクションアダプタに委譲するstrategyオブジェクトをマイグレーションで使う。利用側(consumer)は、カスタムのstrategyオブジェクトを実行することでマイグレーションの実行方法を変更できるようになる。
Adrianna Chang
同CHANGELOGより
参考: config.active_record.migration_strategy
-- Rails アプリケーションを設定する - Railsガイド
参考: Strategy パターン - Wikipedia
参考: 週刊Railsウォッチ20220704: マイグレーションをExecutionStrategy
でカスタマイズ可能にする
🔗 Add adapter option disallowing foreign keys by promulo · Pull Request #45301 · rails/rails
アダプタ設定ファイルのオプションで外部キーを禁止できるようになった。
新しい
foreign_keys
オプションはdatabase.yml
に追加可能。これにより、背後のデータベースで外部キー制約がサポートされていても外部キー制約をスキップできるようになる。利用法:
development: <<: *default database: storage/development.sqlite3 foreign_keys: false
Paulo Barros
同CHANGELOGより
参考: 週刊Railsウォッチ20220704: database.ymlでforeign_keys: false
を指定可能になった
🔗 Add configurable deprecation warning for singular associations by HParker · Pull Request #45344 · rails/rails
単数形の関連付けに対する非推奨化警告をコンフィグで設定できるようになった。
このコンフィグは、単数形の関連付け名を
where
内で複数形で参照する非推奨の書き方(遅くなる)に警告を表示するかどうかを制御する。以下の設定にするとパフォーマンスが改善する。
config.active_record.allow_deprecated_singular_associations_name = false
Adam Hess
同CHANGELOGより
このコンフィグは、Rails 7.1ではデフォルトでfalse
になります。
参考: config.active_record.allow_deprecated_singular_associations_name
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20220704: 関連付け先の単数形の名前をwhere
内から複数形で参照すると警告を出す
🔗 Run transactional callbacks on instances most likely to match DB state by cbothner · Pull Request #45280 · rails/rails
トランザクション内でレコードを
save
すると、最も新しいインスタンスでトランザクションコールバックを実行するようになった。1つのトランザクション内で複数のActive Recordインスタンスが同じレコードを変更する場合、そのうちの1つだけが
after_commit
やafter_rollback
を実行する。
Railsでどのインスタンスがコールバックを受け取るかを指定できるよう、config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
コンフィグが追加された。フレームワークはデフォルトで新しいロジックを使うよう変更された。
config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction
がtrue
の場合は、インスタンスのステートがstaleしていても(=古くなっても)、最初に保存したインスタンスでトランザクションコールバックが実行される。
これがfalse
の場合は7.1からフレームワークのデフォルトになるが、トランザクションコールバックはステートが最新のインスタンスで実行される。インスタンスは以下のように選択される。
- 一般に、トランザクションコールバックは最新のインスタンスで実行され、トランザクション内で指定のレコードを保存する。
- ただし例外が2つある。
- トランザクション内でレコードを作成して別のインスタンスで更新すると、
after_create_commit
は2番目のインスタンスで実行される。これは、インスタンスのステートに基づいてナイーブに実行されるafter_update_commit
コールバックの代わりとなる。- レコードがトランザクション内で削除されると、
after_destroy_commit
コールバックは最後に削除されたインスタンスで実行される。これは、たとえstaleしたインスタンスがその後更新を行ったとしても同様で、この更新はどの行にも影響しない。Cameron Bothner and Mitch Vollebregt
同CHANGELOGより
参考: 週刊Railsウォッチ20220620: トランザクション内に同一モデルのインスタンスが複数ある場合にどのインスタンスからコールバックを呼び出すかを変更
🔗 Add :strict
option to default SQLite database.yml template by fatkodima · Pull Request #45346 · rails/rails
SQLite3Adapter
で"strict strings"モードを有効にした。SQLite3で"strict strings"モードを設定することで、二重引用符(
""
)で囲まれた文字列リテラルが無効になった。SQLite3では、二重引用符で囲んだ文字列リテラルにいくつかの癖がある。
最初は二重引用符で囲んだ文字列を識別子名とみなそうとするが、存在しない場合は文字列リテラルとみなす。この振る舞いのせいで、タイポがあっても通知されない。たとえば、存在しないカラムに対してインデックスを作成できてしまう。
詳しくは以下のSQLite3ドキュメントを参照。この振る舞いを無効にしたい場合は、以下の設定で行える。
# config/application.rb config.active_record.sqlite3_adapter_strict_strings_by_default = false
修正: #27782
fatkodima, Jean Boussier
同CHANGELOGより
参考: config.active_record.sqlite3_adapter_strict_strings_by_default
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20220620: SQLiteのdatabase.ymlにデフォルトで:strict
オプションを追加
🔗 Update AR Relation method to reset cache_version by austenmadden · Pull Request #45342 · rails/rails
リレーションの
cache_version
がstaleする(古くなる)可能性がある問題を修正。従来は、リレーションオブジェクトで
reset
を呼び出しても@cache_versions
がリセットされていなかったため、最新の正しいデータがあるにもかかわらず、古いcache_version
の値が返されて混乱することがあった。利用法:
developers = Developer.all developers.cache_version Developer.update_all(updated_at: Time.now.utc + 1.second) developers.cache_version # cache_versionがstaleする developers.reset developers.cache_version # 最新の正しいcache_versionを返す
修正: #45341
Austen Madden
同CHANGELOGより
参考: 週刊Railsウォッチ20220620: Active Recordリレーションのreset
でcache_version
がリセットするよう修正
🔗 Add support for exclusion constraints (PostgreSQL-only) by agrobbin · Pull Request #40224 · rails/rails
(PostgreSQLのみ)EXCLUDE制約をサポート。
add_exclusion_constraint
remove_exclusion_constraint
add_exclusion_constraint :invoices, "daterange(start_date, end_date) WITH &&", using: :gist, name: "invoices_date_overlap" remove_exclusion_constraint :invoices, name: "invoices_date_overlap"
EXCLUDE制約について詳しくはPostgreSQLドキュメントの
CREATE TABLE ... EXCLUDE ...
を参照。Alex Robbin
同CHANGELOGより
参考: 週刊Railsウォッチ20220620: (PostgreSQLのみ)EXCLUDE制約のサポートが追加
🔗 change_column_null
should raise if a non-boolean 3rd argument is provided by ghiculescu · Pull Request #45229 · rails/rails
change_column_null
の第3引数がブーリアンでない場合はエラーを発生するよう修正。従来は、
change_column_null
の第3引数がブーリアンでない場合にtruthyとして扱われ、カラムがnull許容になった。この振る舞いは予想に反するので、true
またはfalse
のみを渡せるよう変更された。change_column_null :table, :column, true # good change_column_null :table, :column, false # good change_column_null :table, :column, from: true, to: false # raiseする(従来はnullableカラムになった)
Alex Ghiculescu
同CHANGELOGより
参考: 週刊Railsウォッチ20220620: change_column_null
にブーリアン以外の値を渡すとエラーになるように修正
🔗 Enforce limit on table names length by fatkodima · Pull Request #45136 · rails/rails
テーブル名の長さに上限を設けた。
修正: #45130
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20220620: テーブル名の長さに上限を設定
🔗 Correct minimum MariaDB version for CHECK_CONSTRAINTS by elebow · Pull Request #45326 · rails/rails
CHECK制約サポートのため、MariaDBの最小バージョン指定を
10.2.22
に修正。Eddie Lebow
同CHANGELOGより
🔗 Fix Hstore deserialize regression by edsharp · Pull Request #45222 · rails/rails
PostgreSQLの
Hstore
データ型のデシリアイズで再発した不具合を修正。edsharp
同CHANGELOGより
参考: PostgreSQL 15ドキュメント F.18. hstore
🔗 Add validity for PostgreSQL indexes by fatkodima · Pull Request #45160 · rails/rails
PostgreSQLインデックスの有効性をチェックする
valid: true
オプションを追加。connection.index_exists?(:users, :email, valid: true) connection.indexes(:users).select(&:valid?)
fatkodima
同CHANGELOGより
参考: 週刊Railsウォッチ20220606: PostgreSQL用のindex_exists?
にvalid:
キーワード引数が追加
🔗 Fix eager loading models without primary keys by mattalat · Pull Request #43402 · rails/rails
主キーがないモデルの
eager_load
が正しく行われない問題を修正。Anmol Chopra, Matt Lawrence, and Jonathan Hefner
同CHANGELOGより
プルリクメッセージには、通常のActive Recordでも、データベースVIEWを使っている場合や、以下のようなメソッドチェインでこの問題が起きていたと書かれています。
my_instance.includes(:model_without_primary_key).order('model_without_primary_key.name')
参考: 週刊Railsウォッチ20220606: 主キーのないモデルのeager_load
を修正
🔗 Avoid validating a unique field if it has not changed and is backed by a unique index by fatkodima · Pull Request #45149 · rails/rails
uniqueインデックスのあるフィールドで変更が生じなかった場合は、フィールドの
uniqueness
バリデーションを回避するようになった。従来は、レコードを
save
したときにuniqueness
バリデーションが設定されている属性でuniqueness
チェックのためのクエリが余分に送信されていた。これは属性に変更がなかった場合でも発生していた。これに対応するuniqueインデックスがデータベース側にあれば、永続化でこのバリデーションが失敗することはありえないので、このバリデーションを安全にスキップできる。
fatkodima
同CHANGELOGより
参考: §2.12 uniqueness
-- Active Record バリデーション - Railsガイド
参考: 週刊Railsウォッチ20220531: uniqueness指定のフィールドが変更されていない場合のバリデーションを回避
🔗 no longer set sql_auto_is_null by HParker · Pull Request #45134 · rails/rails
MySQLアダプタで
variables["sql_auto_is_null"] = 0
を設定しないようになった。この設定はMySQL 5.5以降デフォルトでオフになったので、手動でわざわざオフにする必要はない。
Adam Hess
同CHANGELOGより
参考: PDF MySQL 5.5 Release Notes
🔗 Fix touch
to raise an error for readonly columns by fatkodima · Pull Request #45125 · rails/rails
attr_readonly
カラムにtouch
したらActiveRecord::ActiveRecordError
を発生するよう修正。fatkodima
同CHANGELOGより
同プルリクメッセージでは以下のように書かれています。
update_attribute
およびupdate_attributes
ではエラーになる- 属性への代入や
update
は、readonly属性についてはsave
時に単に無視される(以下のAPIドキュメントに書かれている通り)。
参考: Rails API attr_readonly
-- ActiveRecord::ReadonlyAttributes::ClassMethods
🔗 Add ability to ignore tables by regexp for SQL schema dumps by fatkodima · Pull Request #45091 · rails/rails
SQLスキーマダンプで除外したいテーブルを正規表現で指定できるようになった。
ActiveRecord::SchemaDumper.ignore_tables = [/^_/]
fatkodima
同CHANGELOGより
参考: ActiveRecord::SchemaDumper.ignore_tables
-- Rails アプリケーションを設定する - Railsガイド
🔗 Avoid query from calculations on contradictory relation by luanzeba · Pull Request #45030 · rails/rails
矛盾のあるリレーションで計算メソッドを実行するときにクエリ送信を回避するよう修正。
従来は、
User.where(id: []).count
のように矛盾のあるリレーションを渡すと計算時にクエリが送信されていた。修正により、このようなシナリオでクエリを送信しなくなった。該当する計算メソッドは以下のとおり。
count
sum
average
minimum
maximum
Luan Vieira, John Hawthorn and Daniel Colson
同CHANGELOGより
参考: §22 計算 -- Active Record クエリインターフェイス - Railsガイド
🔗 Allow using aliased attributes with insert_all
/upsert_all
by fatkodima · Pull Request #45036 · rails/rails
insert_all
とupsert_all
でエイリアス属性も指定できるようになった。class Book < ApplicationRecord alias_attribute :title, :name end Book.insert_all [{ title: "Remote", author_id: 1 }], returning: :title
fatkodima
同CHANGELOGより
参考: Rails API insert_all
-- ActiveRecord::Persistence::ClassMethods
参考: Rails API upsert_all
-- ActiveRecord::Persistence::ClassMethods
🔗 Support encrypted attributes on columns with default values by jorgemanrubia · Pull Request #45033 · rails/rails
カラムの暗号化属性でデータベースのデフォルト値をサポート。
これにより、カラムに定義された暗号化属性にデフォルト値を設定できるようになる。値は作成時に暗号化される。
改修前は、config.active_record.encryption.support_unencrypted_data
にtrue
を設定しないとエラーになっていた。Jorge Manrubia and Dima Fatko
同CHANGELOGより
参考: §6.1.1 config.active_record.encryption.support_unencrypted_data
-- Active Record と暗号化 - Railsガイド
参考: 週刊Railsウォッチ20220516: デフォルト値付きのカラムで暗号化属性をサポート
🔗 Multi database: define reading_request?
in resolver by ghiculescu · Pull Request #44944 · rails/rails
DatabaseSelector::Resolver
ミドルウェアのreading_request?
がオーバーライド可能になった。デフォルトの実装ではリクエストが
get?
またはhead?
かどうかをチェックしているが、この振る舞いを自由に変更できるようになった。
このメソッドがtrue
を返すとResolver#read
が呼び出されるようになり、リクエストがreplicaデータベースによっても配信されるようになる。Alex Ghiculescu
同CHANGELOGより
参考: Rails API ActiveRecord::Middleware::DatabaseSelector
🔗 Remove legacy_connection_handling by eileencodes · Pull Request #44827 · rails/rails
Rails 6.1から非推奨化されていた
ActiveRecord.legacy_connection_handling
を削除。Eileen M. Uchitelle
同CHANGELOGより
参考: §2.1 データベース単位のコネクション切り替え -- Ruby on Rails 6.1 リリースノート - Railsガイド
参考: 週刊Railsウォッチ20220411: legacy_connection_handling
を削除
🔗 rails db:schema:{dump,load}
now checks ENV["SCHEMA_FORMAT"]
before config by ghiculescu · Pull Request #44834 · rails/rails
rails db:schema:{dump,load}
でコンフィグ前にENV["SCHEMA_FORMAT"]
をチェックするようになった。
rails db:structure:{dump,load}
は既に非推奨化されているため、スキーマをSQL形式とRuby形式のどちらでも手軽に(=コンフィグを変更せずに)ダンプできる方法がなかった。
この改修により、以下のように環境変数を設定することでこれを行えるようになった。SCHEMA_FORMAT=sql rake db:schema:dump
Alex Ghiculescu
同CHANGELOGより
この変更は、Rails 7.0.4でリリース済みです。
なおconfig.active_record.schema_format
のデフォルトは:ruby
です。
参考: §3.8.10 config.active_record.schema_format
-- Rails アプリケーションを設定する - Railsガイド
🔗 Fixed MariaDB default function by kaspernj · Pull Request #44654 · rails/rails
MariaDBでのデフォルトSQL関数サポートを修正。
db/schema.rbへのダンプでデフォルト関数名が正しく書き込まれていなかったため、
db:schema:load
を実行しても正しく動作しなかった。今後、より多くの関数が新規レコードの保存で文字列コンテンツとして追加されるようになるだろう。kaspernj
同CHANGELOGより
参考: 週刊Railsウォッチ20220328: MariaDBのデフォルト関数サポートを修正
🔗 Add active_record.destroy_association_async_batch_size
configuration by nholden · Pull Request #44617 · rails/rails
非同期バッチサイズを指定する
active_record.destroy_association_async_batch_size
コンフィグを追加。これにより、アプリケーションでの関連付けに
dependent: :destroy_async
オプションを指定して、単一のバックグラウンドジョブで削除する最大レコード数を指定できるようになる。デフォルトでは、現在の振る舞いを変えない(親レコードを削除すると、すべての依存レコードが単一のバックグラウンドジョブで削除される)。依存レコード数がこの設定を超えると、レコードの削除が複数のバックグラウンドジョブに分割されるようになる。Nick Holden
同CHANGELOGより
参考: config.active_record.destroy_association_async_batch_size
-- Rails アプリケーションを設定する - Railsガイド
🔗 Fix remove_foreign_key
with :if_exists
option when foreign key actually exists by fatkodima · Pull Request #44637 · rails/rails
remove_foreign_key
に:if_exists
オプションを指定すると、外部キーが実際に存在している場合にエラーになっていたのを修正。fatkodima
同CHANGELOGより
参考: §3.7 外部キー -- Active Record マイグレーション - Railsガイド
🔗 Remove --no-comments
from Postgres structure dump command by ghiculescu · Pull Request #44633 · rails/rails
PostgreSQLのstructure dumpの
--no-comments
フラグを廃止。これにより、スキーマでカスタムコメントを使っている一部のアプリが動かなくなる。
structureダンプにコメントを含めたくない場合は、以下を設定できる。ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-comments']
Alex Ghiculescu
同CHANGELOGより
参考: §6 Structure Dumpについて -- Active Record と PostgreSQL - Railsガイド
🔗 Reduce the memory footprint of fixtures accessors by casperisfine · Pull Request #44528 · rails/rails
フィクスチャのアクセサでメモリフットプリントを削減。
従来は、フィクスチャのアクセサを
define_method
でeagerに定義していたため、フィクスチャやテストスイートの量が増えるとメモリ使用量に直接影響していた。改修後は、フィクスチャのアクセサを
method_missing
で実装したことで、メモリやCPUのオーバーヘッドが大きく軽減される。Jean Boussier
同CHANGELOGより
参考: 週刊Railsウォッチ20220308: フィクスチャのメモリフットプリントを削減
参考: Module#define_method
(Ruby 3.2 リファレンスマニュアル)
参考: BasicObject#method_missing
(Ruby 3.2 リファレンスマニュアル)
🔗 Fix config.active_record.destroy_association_async_job
configuration by nholden · Pull Request #44309 · rails/rails
config.active_record.destroy_association_async_job
コンフィグの不具合を修正。
config.active_record.destroy_association_async_job
は、dependent: :destroy_async
オプションを指定したhas_many
関連付けに対して行う削除をバックグラウンドで実行できるようにすべき。
従来はこのdependent: :destroy_async
オプションが無視されていたため、ActiveRecord::DestroyAssociationAsyncJob
による削除が常にバックグラウンドで実行されていた。Nick Holden
同CHANGELOGより
参考: config.active_record.destroy_association_async_job
-- Rails アプリケーションを設定する - Railsガイド
参考: 週刊Railsウォッチ20220221: Active Recordのdestroy_association_async_job
コンフィグが効くように修正
🔗 Fix change_column_comment
to preserve column's AUTO_INCREMENT in the MySQL adapter by fatkodima · Pull Request #44480 · rails/rails
MySQLアダプタ:
change_column_comment
でカラムのAUTO_INCREMENT
が失われないよう修正。fatkodima
同CHANGELOGより
参考: Rails API change_column_comment
-- ActiveRecord::ConnectionAdapters::SchemaStatements
🔗 Handle quoting of Rational numbers for MySQL by kmcphillips · Pull Request #44404 · rails/rails
MySQLアダプタで、数値が
ActiveSupport::Duration
とRational
の場合の引用符処理を修正。Kevin McPhillips
同CHANGELOGより
参考: 週刊Railsウォッチ20220221: mysql2アダプタでActiveSupport::Duration
を適切に扱うよう修正
🔗 Allow column name with COLLATE as safe SQL string by shugo · Pull Request #44384 · rails/rails
order
でカラムにCOLLATE
を指定した場合(例:title COLLATE "C"
)にも、SQL関数を指定したときと同様に安全なSQL文字として扱えるようになった。Shugo Maeda
同CHANGELOGより
参考: Allow column name with function (e.g. length(title)
) as safe SQL string by kamipo · Pull Request #36448 · rails/rails
参考: 週刊Railsウォッチ20220221: order
でCOLLATE
を安全なSQL文字列として使えるようになった
参考: PostgreSQL 15ドキュメント 24.2. 照合順序サポート
参考: MySQL :: MySQL 8.0 リファレンスマニュアル :: 10.8.1 SQL ステートメントでの COLLATE の使用
🔗 Accept _
integer notation in VERSION arg to database tasks · rails/rails@ef4bf94
データベース用rakeタスクの
VERSION
引数でアンダースコア(_
)も使えるようになった。Eddie Lebow
同CHANGELOGより
参考: 週刊Railsウォッチ20220221: DBのrakeタスクでVERSION
envの数値に_
が使えるようになった
🔗 Reverse the order of INSERT
statements in structure.sql
dumps by ghiculescu · Pull Request #44363 · rails/rails
structure.sql
ダンプのINSERT
ステートメントで値の並び順を逆にした。これにより、マージで競合する可能性が減るはず。
新しいマイグレーションでは、新しい値がリストのトップに追加されるようになる。ただし、既存のアプリでは次回
structure.sql
を生成したときに大量の差分が発生することになる。Alex Ghiculescu, Matt Larraz
同CHANGELOGより
🔗 Postgres adapter passes keywords in a deprecated way (Ruby 2.7, ActiveRecord 6.1.4) · Issue #44307 · rails/rails
Ruby 2.7とActive Record 6.1.4で
PG.connect
にキーワード引数を渡すと非推奨警告が表示されていたのを修正。修正: #44307
Nikita Vasilevsky
同CHANGELOGより
この修正は、Rails 7.0.2でリリース済みです。
🔗 Fix rollbacks following serialization failures or deadlocks by zarqman · Pull Request #44127 · rails/rails
シリアライズが失敗してデッドロックした後でデータベースコネクションが切断されるバグを修正。
6.1.4より前は、シリアライズが失敗してデッドロックすると、実際のトランザクションとsavepointの両方でロールバックが発行されていた。MySQLはデッドロック後にsavepointのロールバックを許さないため、これによって壊れてしまう。
6.1.4では実際のトランザクションとsavepointの両方でロールバックが削除されたが、これによってデータベースコネクションのステートがunknownになり、切断されてしまう。
この修正によって、MySQLのsavepointを除いてロールバックが復元されるようになった。
Thomas Morgan
同CHANGELOGより
🔗 Fiber-safe ConnectionPool by machty · Pull Request #44219 · rails/rails
ActiveRecord::ConnectionPool
がFiberセーフになった。
ActiveSupport::IsolatedExecutionState.isolation_level
で:fiber
を指定すると、コネクションプールからコネクションをチェックアウトする同一のThreadからの複数のFiberをサポートするようになる。Alex Matchneer
同CHANGELOGより
🔗 Add ActiveRecord::Persistence#update_attribute! by drewtempelmeyer · Pull Request #44141 · rails/rails
ActiveRecord::Persistence
にupdate_attribute!
を追加。
update_attribute
と同様だが、before_*
コールバックで:abort
がスローされた場合はActiveRecord::RecordNotSaved
をraiseする点が異なる。class Topic < ActiveRecord::Base before_save :check_title def check_title throw(:abort) if title == "abort" end end topic = Topic.create(title: "Test Title") # #=> #<Topic title: "Test Title"> topic.update_attribute!(:title, "Another Title") # #=> #<Topic title: "Another Title"> topic.update_attribute!(:title, "abort") # raises ActiveRecord::RecordNotSaved
Drew Tempelmeyer
同CHANGELOGより
参考: Rails API update_attribute
-- ActiveRecord::Persistence
参考: 週刊Railsウォッチ20220117: update_attribute!
が追加
🔗 Avoid eager loading in Relation#pretty_print by BuonOmo · Pull Request #43302 · rails/rails
ActiveRecord::Relation
の#pretty_print
で全レコードの読み込みを回避するようになった。# 修正前 pp Foo.all # 全テーブルを読み込む # 修正後 pp Foo.all # 10件まで表示し、残りを"..."で表示
Ulysse Buonomo
同CHANGELOGより
参考: 週刊Railsウォッチ20220117: Relation#pretty_print
のeager loadingを回避
🔗 QueryMethods#in_order_of
drop records not listed by kddnewton · Pull Request #44097 · rails/rails
QueryMethods
の#in_order_of
メソッドで、指定の値にないレコードをWHERE
で除外するように変更。
Enumerable
のin_order_of
と振る舞いを合わせるため、QueryMethods
のin_order_of
に渡した値のリストで絞り込んだものを並べ替えるようにした。Kevin Newton
同CHANGELOGより
# 同PRのAPIドキュメントより
User.in_order_of(:id, [1, 5, 3])
# SELECT "users".* FROM "users"
# ORDER BY FIELD("users"."id", 1, 5, 3)
# WHERE "users"."id" IN (1, 5, 3)
注: このプルリクによって、#43916の「指定外のレコードのソート順も維持する振る舞い」が打ち消されました。
参考: この改修はRails 7.0.1でリリース済みです。
Rails 7: クエリ結果を任意の順序にできるActiveRecord::QueryMethods#in_order_of
🔗 Allow named expression indexes to be revertible. by oliverguenther · Pull Request #43333 · rails/rails
名前付きの式インデックスをロールバックできるよう修正。
従来は、リバーシブル(取り消し可能)なマイグレーションのロールバックで以下のコードがエラーになった(インデックスの削除でこのインデックス名が使われていなかったため)。
add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
修正: #43331
Oliver Günther
同CHANGELOGより
🔗 Updating the --no-comment argument to the correct --no-comments argument by aldent95 · Pull Request #44028 · rails/rails
PostgreSQLのstructure dumpタスクのヘルプ説明文にある引数名のスペルを修正。
Rails 7で追加された
--no-comment
引数を正しい--no-comments
(複数形)に更新した。Alex Dent
同CHANGELOGより
🔗 Fix migration compatibility to create SQLite references/belongs_to column as a integer when migration version is 6.0 by marcelolx · Pull Request #43295 · rails/rails
マイグレーションのバージョンが6.0の場合に、SQLite3の
references
カラムとbelongs_to
カラムがinteger
型として作成されるよう修正。バージョン6.0の
references
カラムとbelongs_to
カラムが、SQLite3のアダプタでinteger
型ではなくbigint
型で作成されていた。Marcelo Lauxen
同CHANGELOGより
この修正は、Rails 6.1.5でリリース済みです
🔗 Fix QueryMethods#in_order_of
to handle empty order list by casperisfine · Pull Request #43916 · rails/rails
QueryMethods
の#in_order_of
に空のリストを渡せるよう修正。Post.in_order_of(:id, []).to_a
また、このカラムを明示的に第2ソート順として設定することで、指定以外の値のソート順を維持するようになった。
Jean Boussier
同CHANGELOGより
注: 指定以外の値のソート順を維持する振る舞いは、その後#44097でなくなりました。
この改修は、Rails 7.0.1でリリース済みです。
Rails 7: クエリ結果を任意の順序にできるActiveRecord::QueryMethods#in_order_of
🔗 Properly quote autogenerated column aliases by casperisfine · Pull Request #43911 · rails/rails
計算系メソッドによって生成されるカラムエイリアスを正しく引用符で囲むよう修正。
このエイリアスはテーブル名から導出されるので、有効な識別子を得られるという前提が成り立つとは限らない(テーブル名が数字始まりの場合など)。
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
同CHANGELOGより
🔗 Add authenticate_by when using has_secure_password by jonathanhefner · Pull Request #43765 · rails/rails
has_secure_password
にauthenticate_by
メソッドを追加。この
authenticate_by
メソッドは、以下のようなコードを置き換えるのが目的。このコードは、メールアドレスが一致するユーザーが見つからない場合に、見つかった場合よりも早期に処理が終了してしまう。User.find_by(email: "...")&.authenticate("...")
このようなコードは、タイミングベースの列挙攻撃に対して脆弱である。攻撃者はこの脆弱性を使って、特定のメールアドレスを持つユーザーアカウントが存在するかどうかを検索時間の違いで判定可能になる。アカウントが存在することを攻撃者が確認できたら、他のデータベースから漏洩したパスワードの中から、そのメールアドレスに関連付けられたパスワードを試せるようになる。これは、ユーザーが同じパスワードを複数のサイトで使い回すというありがちな運用で起こる可能性がある。さらに、攻撃者がアカウントのメールアドレスを手に入れれば標的型フィッシング("spear phishing")攻撃を試みることも可能になる。
authenticate_by
は、メールアドレスが一致するユーザーが見つかった場合にかかる時間と、一致するユーザーが見つからない場合にかかる時間を同じにすることで、この脆弱性を修正する。User.authenticate_by(email: "...", password: "...")
Jonathan Hefner
同CHANGELOGより
注: その後、パスワードが空の場合の修正も7.1.0.beta1に含まれました↓。
以前の変更については7-0-stableのCHANGELOGを参照。
関連記事
Rails 7.1に入る主要な機能まとめ(2)error_highlight対応、routes --grepほか(翻訳)
概要
MITライセンスに基づいて翻訳・公開いたします。
参考: Active Record の基礎 - Railsガイド
参考: Active Record マイグレーション - Railsガイド
参考: Active Record コールバック - Railsガイド
参考: Active Record の関連付け - Railsガイド
参考: Active Record クエリインターフェイス - Railsガイド
参考: Active Record と暗号化 - Railsガイド
参考: Active Record で複数のデータベース利用 - Railsガイド