This Week in Rails: パフォーマンス最適化と後方互換性の改善
Rails 8.1では、Active Record暗号化によるパラメータフィルタリングのパフォーマンス問題を解決する一連のPRがマージされました。これらの変更により、暗号化属性を持つモデルが増えてもフィルタリング処理が効率的に動作し、同時にRails 8.0からの移行時の互換性問題も修正されています。
背景
Active Record暗号化機能は、すべての暗号化属性に対して深いネスト構造のフィルタパターンを自動登録します。#56759 の報告によると、暗号化属性を持つモデルが増えるにつれて filter_parameters が数千のエントリに膨れ上がり、巨大な正規表現が生成されてパラメータフィルタリングが極めて遅くなる問題が発生していました。
このパフォーマンス劣化は、フィルタパターンの組み合わせ爆発と、フィルタリング対象外のイベントでもペイロードを構築していた非効率な実装に起因していました。
技術的な変更
フィルタパターンの組み合わせ爆発の解消
#56759 は、filter_parameters の肥大化を防ぐための基盤を整備しました。暗号化属性が増えても登録されるフィルタパターンが指数的に増加しないよう、パターン管理を最適化しています。
#56762 は、ActiveSupport::ParameterFilter のプリコンパイル段階で冗長なパターンを除去します。Active Record暗号化が自動登録する深いネストパターンから、デッドコード除去の手法を用いて不要なフィルタを削除することで、正規表現のサイズとマッチング時間を削減しています。
イベントフィルタリングの効率化
#56761 は、EventReporter でのイベントフィルタリングをペイロード構築前に実行するよう変更しました。
変更前:
フィルタリング対象のイベントでも完全なペイロードを構築してからフィルタリングしていました。
変更後:
イベント名のみを使ってフィルタリングを判定し、フィルタリング対象外のイベントのみペイロードを構築します。これにより、無駄なペイロード構築のコストが削減されます。
Rails 8.0からの互換性問題の修正
#56768 は、Rails 8.0でシリアライズされた ActiveModel::Type::Integer オブジェクトをRails 8.1でデシリアライズする際に NoMethodError が発生する問題を修正しました。Rails 8.1では @max と @min の初期化方法が変更されていましたが、古い形式でシリアライズされたオブジェクトではこれらの値が nil になっていました。
修正後は、limit 属性から @max と @min を遅延初期化することで、Rails 8.0のデータとの後方互換性を確保しています。
#56767 は、ActiveRecord::Type::Json でのJSON Encoderのキャッシュタイミングを修正しました。クラスが最初に参照された時点でエンコーダをキャッシュしていたため、その後のカスタマイズが反映されない問題がありました。修正後は ActiveSupport::JSON のキャッシュ済みエンコーダを使用することで、この制限を解消しています。
その他の重要な変更
トランザクション制御の拡張ポイント追加
#56732 は、save や destroy などの永続化メソッドで暗黙的に作成されるトランザクションをカスタマイズできるようにしました。トランザクション作成をオーバーライド可能なプライベートメソッドに抽出することで、モデルごとにトランザクション動作を完全に制御できます。
複合キーでの has_many :through の修正
#56703 は、ThroughReflection#association_primary_key が複合主キーの配列を .to_s で文字列化していた問題を修正しました。これにより、複合主キーを持つ関連で _ids リーダーメソッドを呼び出した際の UnknownAttributeReference エラーが解消されます。
非推奨化と削除
#56778 は Mail::Address.wrap をRails 8.2での削除に向けて非推奨化しました。#56777 は、既に非推奨だった ActiveSupport::Multibyte::Chars クラスと String#mb_chars メソッドを削除しています。
まとめ
今週のRailsは、Active Record暗号化に起因するパフォーマンス問題を多角的に解決する変更が中心でした。フィルタパターンの最適化、イベントフィルタリングの効率化、そして後方互換性の確保により、暗号化機能を使用するアプリケーションでも高いパフォーマンスを維持できるようになっています。