Active Recordの改善
Active Recordでは、パフォーマンスの向上、マイグレーションの簡素化、トラブルシューティングの改善などが実施されています。
フィクスチャの一括挿入
SQLiteアダプタの改良により、SQLiteデータベースにおいてフィクスチャの一括挿入がサポートされるようになりました。従来は、以下のように1件のフィクスチャに対して1個のINSERTコマンドが実行されていました。
INSERT INTO "person" ("id", "name", "birth", "created_at", "updated_at") VALUES (1, 'Nao', 1970, '2024-08-11 05:51:09.160917', '2024-08-11 05:51:09.160917'); INSERT INTO "person" ("id", "name", "birth", "created_at", "updated_at") VALUES (2, 'Shino', 1980, '2024-08-11 05:51:09.160917', '2024-08-11 05:51:09.160917')
件数が多い場合のパフォーマンス悪化を防ぐために、Rails 8.0ではSQLiteアダプタの一括挿入機能を用いて、1個のテーブルに対して1個のINSERTコマンドに集約するようになりました。
INSERT INTO "person" ("id", "name", "birth", "created_at", "updated_at") VALUES (1, 'Nao', 1970, '2024-08-11 05:51:09.160917', '2024-08-11 05:51:09.160917'),(2, 'Shino', 1980, '2024-08-11 05:51:09.160917', '2024-08-11 05:51:09.160917')
この改善により、SQLiteを使用した環境におけるテストの高速化が期待されます。
drop_tableメソッドが複数テーブルの削除に対応
Rails 8.0では、drop_tableメソッドにおいて複数のテーブルを一度に削除できるようになりました。具体的には、テーブル名の配列を引数として渡すことで、配列に含まれるテーブルが全て一度に削除されます。従来は、以下のようにテーブルごとにdrop_tableメソッドを呼び出す必要がありました。
drop_table(:users) drop_table(:products) drop_table(:customers)
Rails 8.0では、以下のようにひとつのdrop_tableメソッドで複数テーブルを削除できます。
drop_table([:users, :products, :customers)
新規データベースのマイグレーションにスキーマを読み込み
まっさらのデータベースにrails db:migrateコマンドでマイグレーションを実行する場合、それに先立ちデータベーススキーマをまず読み込むことになりました。本来は、マイグレーションの履歴を古いものから実行するのが正式ですが、データベーススキーマを利用して一気に最新の状態のテーブルを構築します。
これは、新規のデータベースでは既存データの維持は不要なので、最終的なテーブルを構築すれば目的を果たせるからです。その分、マイグレーションの速度が向上し、マイグレーションの各段階で予期せぬエラーに遭遇することも回避できます。
Railsでは、個々のマイグレーションファイルとは別に、最新のテーブルの状態に相当するスキーマファイルdb/schema.rbが自動で生成されています。rails db:schema:loadコマンドでスキーマファイルをデータベースに反映できますし、rails db:resetコマンドでデータベースを初期化してスキーマファイルで再構成することもできます。
クエリログのタグを既定で有効化
Rails 8.0では、development環境におけるクエリログのタグを既定で有効にするようになりました。これにより、SQL文に問題があった場合、その文を生成したコードまで遡ってトラッキングすることが可能になります。また、どのデータベースが使われているかもログにより特定できるので、複数のデータベースを使っている環境でも有用です。
クエリログのタグとは、Rails 7.0で実装された、発行されるSQL文にコメントを自動で付与する機能です。Rails 7.0では、既定値は無効となっていました。
Parameters: {"token"=>"[FILTERED]"} User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 4 LIMIT 1 /*action='edit',application='Authapp',controller='passwords'*/ ↳ app/controllers/passwords_controller.rb:29:in `set_user_by_token'
このように、/* ~ */の形式で、コメントが付与されます。コメントの内容は、アプリケーション、コントローラー、アクションが既定となっています。これだけで、どのアクションで問題のSQL文を生成しているかが分かりやすくなります。
クエリログのタグ機能は、config/environments/development.rbファイルにて以下のようにquery_log_tags_enabledパラメータにtrueを設定することで有効になっています。
config.active_record.query_log_tags_enabled = true
コメントに出力する内容は、query_log_tagsパラメーターにActiveRecord::QueryLogsで用意されているタグを指定することでカスタマイズできます。
config.active_record.query_log_tags = [ :application, # アプリケーション :db_host, # データベースのホスト :database, # データベース :pid # プロセスID ]
必要に応じてProduction環境にまで有効にすることで、運用時に発生した問題を特定しやすくなるでしょう。
まとめ
今回は、Ruby on Rails 8.0の新機能のうち、SQLite統合により利用可能になったSolid Adapter、汎用スクリプトのためのscriptフォルダとジェネレータ、デフォルトとなったPropshaft、そしてActive Recordの改善について紹介しました。
Railsは、絶え間ない進化を成し遂げています。次の進化でも、改めてその概要をお伝えできればと思います。