Rails 7がまもなく登場!主要な新機能とアップグレードのポイントを徹底解説
Rails 7の公開が目前に迫っています。正式なリリース日は確定していませんが、クリスマス前には利用可能になると予想されており、もうすぐそこまで来ています。
本記事の執筆時点での最新バージョンは7.0.0.rc1、つまり最初のリリース候補版(RC)です。Basecamp、HEY、GitHub、Shopifyといった大手企業がすでに本番環境でRails 7のアルファ版を稼働させているため、リリース候補版もかなり安定していることが期待できます。
この記事では、Rails 7がもたらす新機能と変更点について詳しく見ていきます。
Node.jsとWebpackが不要に
そう、お読みの通りです!Rails 7ではJavaScriptの扱いにNodeJSやWebpackが不要になります。しかもnpmパッケージは引き続き利用可能です。
従来、BabelによるES6のトランスパイルやWebpackによるバンドルには多くのセットアップが必要でした。Webpacker gemのおかげでRailsはこれらを比較的うまくサポートしていましたが、それでも多くの複雑さをもたらし、理解や変更が難しく、特にアップグレード性を維持しながらの運用は大きな負担でした。
現在では、rails newで作成される新しいアプリケーションのデフォルトとして、importmaps-rails gemによるインポートマップが採用されています。package.jsonを記述してnpmやyarnで依存関係をインストールする代わりに、./bin/importmap CLIを使って依存関係をピン留め(または解除・更新)します。
例えば、date-fnsをインストールする場合は次のようにします:
これにより、config/importmap.rbに以下のような行が追加されます:
JavaScriptコード内では、これまでと同じように記述できます:
この構成で注意すべき点は、開発者が書いたコードとブラウザが受け取るコードの間にトランスパイルが行われないことです。とはいえ、現在の主要なブラウザはすべてES6を標準でサポートしているため、ほとんどの場合は問題ありません。
ただしその一方で、TypeScriptやJSXは使用前にJSへのトランスパイルが必要なため、この構成では使えないという制約もあります。
そのため、JSXを使ったReactを利用したい場合は、別のセットアップ(webpack / rollup / esbuildなど)を選択する必要があります。
Rails 7はこの作業も代わりに行ってくれます。希望の戦略を指定して、たった1つのコマンドを実行するだけです:
TurbolinksとUJSがTurboとStimulusに置き換え
Rails 7で生成されたアプリケーションには、TurbolinksとUJSの代わりに、HotwireのTurboとStimulusがデフォルトで組み込まれます。Hotwireは、HTMLをネットワーク越しに送信することで高速なDOM更新を実現する新しいアプローチです。
データベース層での暗号化
Rails 7では、ActiveRecord::Baseのencryptsメソッドを使って、特定のデータベースフィールドを暗号化対象としてマークできます。初期設定さえ済ませれば、次のようなコードが書けるようになります:
暗号化された属性は、他の通常の属性と同じように扱えます。データベースとアプリケーション間の暗号化・復号化はRails 7が自動的に処理します。
ただし、少し注意点があります。encryptsメソッドにdeterministic: trueオプションを渡さない限り、そのフィールドを条件にしたデータベース検索はできません。決定論的モードはデフォルトの非決定論的モードよりもセキュリティが低いため、どうしても検索が必要な属性にのみ使用するようにしましょう。
非同期クエリ
データを取得する際にバックグラウンドで結果をフェッチできるload_asyncメソッドが追加されました。これは、1つのコントローラアクションから互いに依存しない複数のクエリを読み込む必要がある場合に特に効果的です。次のように実行できます:
これにより、両方のクエリが同時にバックグラウンドで実行されます。各クエリに200msかかる場合、逐次実行すれば400msかかるところを、合計約200msでデータ取得を完了できます。
Rails 7ではZeitwerkモードが必須に
これは、依然としてクラシックローダーを使用している古いアプリケーションにとって破壊的変更となります。すべてのRails 7アプリケーションはZeitwerkモードを使用する必要がありますが、切り替え自体は非常に簡単です。詳細は公式のZeitwerkアップグレードガイドを参照してください。
その他のRails 7の更新内容
ジョブの無制限リトライ
ActiveJobでは、retry_onのattemptsパラメータに:unlimitedを渡せるようになりました。最大試行回数の制限なしに、ジョブの再試行が続けられます。
名前付きバリアント
ActiveStorageのバリアントに名前を付けられるようになったため、アクセスのたびにサイズを指定する必要がなくなりました。
ハッシュからHTML属性への変換
ビューで使用できる新しいtag.attributesメソッドにより、ハッシュをHTML属性に変換できます:
上記のコードは以下を出力します:
Ruby debuggemが新デフォルトに
デバッグ用のデフォルトgemがbyebugからdebugに変更されました。
byebugを呼び出す代わりに、コード内でdebuggerを呼び出すことでデバッグセッションを開始します。
soleで単一レコードを保証
レコードをクエリする際、結果が必ず1件のみであることを保証したい場合は、従来のfirstやfind_byの代わりに、soleまたはfind_sole_byを呼び出せるようになりました。
関連付けの有無をチェック
IDの存在確認のためにJOINを行う代わりに、where.associated(:association)を使って、レコードに関連付けが存在するかどうかを直接チェックできるようになりました。
コントローラアクションから生成ファイルをストリーミング
コントローラアクション内でsend_streamを使用すると、その場で生成中のファイルのストリーミングを即座に開始できるようになりました。
これによりユーザーは即座に(部分的な)レスポンスを受け取れるため、処理が進行していることを認識できます。Herokuにデプロイしている場合には、さらに嬉しいメリットもあります。
ファイルのストリーミングが即座に開始されるため、Herokuは接続を切断しません。つまり、30秒以上かかる一回限りのファイル生成のために、バックグラウンドジョブに頼る必要がなくなります。
Rails 7へのアップグレード方法
以前のRailsバージョンと同様に、アップグレード手順はシンプルです。現時点で公式のアップグレードガイドはまだ公開されていませんが、基本的な流れは以下の通りです:
- Gemfile内のRailsバージョン番号を変更し(執筆時点では
7.0.0.rc1)、bundle updateを実行します。 bundle exec rails app:updateを実行します。対話型CLIの指示に従って、必要に応じてファイルを追加・置換・修正します。- テストを実行し、すべてが期待どおりに動作することを確認します。
まとめ
バグ修正、新機能、変更点の完全な一覧は、Rails 7のリリースノートで確認できます。現時点では網羅的ではありませんが、今後順次更新されていく予定です。
まだRails 6以下を使用している場合は、Rails 7の正式リリースに伴い、Rails 6.1が「セキュリティ対応のみ」モードに移行し、バグフィックスが提供されなくなる点にご注意ください。同時にRails 5.2はEOL(サポート終了)を迎え、一切の修正が提供されなくなります。
それでは、楽しいコーディングを!
P.S. Ruby Magicの最新記事をいち早く読みたい方は、ぜひRuby Magicニュースレターを購読してください。記事を見逃すことはありません!
Pulkit Goyal
ゲスト著者のPulkitは、シニアフルスタックエンジニア兼コンサルタントです。余暇には自身のブログで開発に関する経験談を発信しています。
Pulkit Goyalの記事一覧はこちら
-
RubyのFiddleで任意のCライブラリを操作する方法 ― 知られざる標準ライブラリの隠れた実力
Fiddleは、Ruby 1.9.xで標準ライブラリに追加された、あまり知られていないモジュールです。Rubyから直接Cライブラリとやり取りできるだけでなく、実行中のRubyインタプリタそのものを調査・改変することさえ可能です。 Fiddleの仕組みは、libffiという広く使われているCライブラリをラップすることに基づいています。libffiは、ある言語で書かれたコードから別の言語で書かれた関数を呼び出せるようにするライブラリです。「ffi」は「Foreign Function Interface(外部関数インターフェース)」の略称です。さらに、Fiddleの活用範囲はC言語にとどまりませ
-
ジュニアRubyistが学ぶべき最重要ツール「Pry」——その理由と使い方を徹底解説
コードのバグを見つけるために、putsステートメントをあちこちに挿入して、実行結果が表示されることをひたすら祈ったことはありませんか?たとえば、こんなコードを書いてみる: puts うまくいった! これをコードに組み込んでターミナルで実行しても、何も表示されない——そんな経験があるのではないでしょうか。あるいは、Ruby開発者向けの高機能なデバッグツールの噂は聞いたことがあるけれど、難しそうで手を出せずにいるのかもしれません。結局、「スパゲッティ方式」のデバッグ、つまりエディタにコードを投げて当たるかどうか確かめる方法に頼ってしまうわけです。しかし、この方法では解決策が見つかる保証はまった