モダンRailsフロントエンドとRuby深掘り実践
InertiaとRailsの高度な統合
InertiaとRailsの応答サイクル
RailsアプリケーションでInertia.jsを使用すると、サーバーとクライアントの間の通信方法が根本的に変わります。従来のRailsアプリが各リクエストに対して完全なHTMLページを生成するのとは異なり、Inertiaは最初のページロード時のみ完全なHTMLを送信します。それ以降のナビゲーションはすべて、XHRリクエストとして非同期で行われます。
この仕組みを詳しく見ていきましょう。ユーザーがリンクをクリックすると、Inertiaがそのリクエストをインターセプトし、JavaScriptのfetch APIを使用してXHRリクエストをRailsサーバーに送信します。Railsのルーターはリクエストを適切なコントローラのアクションにディスパッチし、コントローラはデータを準備します。
ここが重要な部分です。コントローラはHTMLをレンダリングする代わりに、JSONレスポンスを返します。このJSONには、ページコンポーネントの名前と、そのコンポーネントが必要とするデータ(プロップス)が含まれています。Inertia.jsはこのJSONを受け取ると、クライアントサイドで新しいページコンポーネントを動的に読み込み、古いものと入れ替えます。これにより、ページ全体をリロードすることなく、SPA(シングルページアプリケーション)のようなスムーズな遷移が実現されます。
共有データと状態管理
多くのアプリケーションでは、すべてのページで同じデータが必要になります。例えば、現在ログインしているユーザーの名前や通知の件数などです。これらのデータを各コントローラのアクションで毎回渡すのは非効率的です。
ここでInertia::Shareミドルウェアが役立ちます。この機能を使うと、「共有プロップス」を定義できます。共有プロップスは、すべてのInertiaレスポンスに自動的に含まれるデータです。
設定はapp/controllers/application_controller.rbで行うのが一般的です。inertia_shareメソッドを使って、共有したいデータをブロック内で定義します。
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
inertia_share do
{
# 同期的に読み込まれるデータ
current_user: current_user&.as_json(only: [:id, :name, :email]),
flash: {
success: flash.notice,
error: flash.alert
}
}
end
end
この設定により、current_userとflashメッセージが、どのページにアクセスしても常にフロントエンドコンポーネントのプロップスとして利用可能になります。これにより、レイアウトコンポーネントでユーザー名を表示したり、通知メッセージを簡単に表示したりできます。
遅延読み込みとセキュリティ
常にすべての共有データを必要とするわけではありません。例えば、ヘッダーに表示する通知の件数は必要でも、通知の詳細リストは通知ページを開くまで不要な場合があります。このような場合にすべてのデータを毎回読み込むと、パフォーマンスが低下する可能性があります。
Inertiaでは、プロップスを遅延読み込み(Lazy Evaluation)させることができます。データをProcやlambdaでラップするだけで、そのデータはフロントエンドコンポーネントから明示的に要求された場合にのみサーバーから取得されるようになります。これは「部分的なリロード」と呼ばれる機能によって実現されます。
# app/controllers/application_controller.rb
inertia_share do
{
current_user: current_user&.as_json(only: [:id, :name]),
# `notifications` は、コンポーネントが要求したときだけ読み込まれる
notifications: -> { current_user.notifications.unread.limit(5) }
}
end
もう一つの重要な側面はセキュリティです。Railsはデフォルトでを提供していますが、Inertiaはこれをどのように扱うのでしょうか? 心配は無用です。inertia-rails gemが、RailsのCSRFトークンを自動的に管理します。最初のHTMLレスポンスにトークンを埋め込み、以降のXHRリクエストではX-CSRF-Tokenヘッダーにトークンを含めて送信します。これにより、Railsアプリケーションのセキュリティを損なうことなく、シームレスなSPA体験を提供できます。