devcontainer環境のエラーページでエディタリンクを動作させる仕組み
RailsをdevcontainerやDocker環境で実行する際、エラーページの「エディタで開く」リンクがホストマシン上で動作しない問題を解決する RAILS_HOST_APP_PATH 環境変数が追加されました。コンテナ内部のパスをホストマシンのパスに変換することで、コンテナ化された開発環境でもエディタ連携が正常に機能するようになります。
背景
#55295で導入されたエラーページからのエディタ起動機能は、EDITOR または RAILS_EDITOR 環境変数を設定することで、エラー発生時にファイルを直接エディタで開けるようになりました。しかし、devcontainerやDocker環境ではコンテナ内部のパス(例:/workspaces/app/...)がエディタURLに含まれるため、ホストマシン上でそのパスが存在せず、リンクが機能しない問題がありました。
コンテナ化された開発環境は現代のRails開発で一般的になっており、この制約はエディタ連携機能の利用を大きく妨げていました。
技術的な変更
ActionDispatch::DebugView に translate_path_for_editor プライベートメソッドが追加され、エディタURLの生成時にパス変換が行われるようになりました。
パス変換ロジック
translate_path_for_editor は以下の手順でパスを変換します:
def translate_path_for_editor(absolute_path)
path = absolute_path.to_s
host_root = ENV["RAILS_HOST_APP_PATH"].to_s
return path if host_root.empty?
return path unless defined?(Rails) && Rails.respond_to?(:root) && Rails.root
app_root = Rails.root.to_s
prefix = app_root.end_with?(File::SEPARATOR) ? app_root : "#{app_root}#{File::SEPARATOR}"
return path unless path.start_with?(prefix)
relative = path.delete_prefix(prefix)
File.join(host_root, relative)
end
変換の条件判定:
-
RAILS_HOST_APP_PATHが未設定または空文字列の場合は元のパスをそのまま返す(後方互換性の維持) -
Rails.rootが利用可能でない場合は変換しない - ファイルが
Rails.root配下にない場合は変換しない(gemやライブラリのファイルは対象外)
セキュリティ考慮:
prefix = app_root.end_with?(File::SEPARATOR) ? app_root : "#{app_root}#{File::SEPARATOR}"
この処理により、Rails.root が /app の場合に /app2/file.rb のような誤ったマッチを防いでいます。File::SEPARATOR を末尾に付与することで、ディレクトリ境界を正確に判定します。
エディタURL生成への統合
既存の editor_url メソッドに1行の変更のみで統合されています:
def editor_url(location, line: nil)
absolute_path = location&.absolute_path
if absolute_path && line && File.exist?(absolute_path)
editor.url_for(translate_path_for_editor(absolute_path), line)
end
end
ActiveSupport::Editor の既存の仕組みを変更せず、パス変換レイヤーを挟み込む設計です。
使用例
devcontainer環境での設定例:
{
"containerEnv": {
"EDITOR": "code",
"RAILS_HOST_APP_PATH": "${localWorkspaceFolder}"
}
}
パス変換の動作:
-
コンテナ内パス:
/workspaces/myapp/app/models/user.rb -
ホストパス:
/Users/developer/projects/myapp/app/models/user.rb -
生成されるURL:
vscode://file//Users/developer/projects/myapp/app/models/user.rb:42
devcontainerの ${localWorkspaceFolder} 変数はホストマシンのワークスペースパスに自動展開されるため、環境に依存しない設定が可能です。
テストカバレッジ
9つの新規テストが追加され、以下のエッジケースをカバーしています:
-
RAILS_HOST_APP_PATH未設定時の動作 - 空文字列設定時の動作
-
Rails.root配下のファイルの変換 -
Rails.root外のファイル(gemなど)の非変換 - パス末尾のセパレータ処理
- ディレクトリ名の誤マッチ防止
テストは ActionDispatch::DebugView の内部メソッドに直接アクセスし、パス変換ロジックの正確性を検証しています。
設計判断
環境変数による設定方式 が採用されました。devcontainer の containerEnv 設定や Docker Compose の environment セクションで簡潔に指定できるため、コンテナ環境との親和性が高い選択です。
Rails.root 配下のファイルのみを変換対象とする 制約により、gemやRuby標準ライブラリのファイルは変換されません。これらのファイルはホストマシン上の異なる場所(例:~/.rbenv/versions/)に存在するため、アプリケーションコードと同じ変換ルールを適用すると誤ったパスになります。
既存のエディタ連携機構を拡張する方式 により、新たな設定キーや抽象化レイヤーを追加せず、1つの環境変数のみで機能を実現しています。ActiveSupport::Editor の実装には一切手を加えず、ActionDispatch::DebugView 内でパス変換を完結させる設計です。
まとめ
本PRは、devcontainerやDockerでのRails開発において、エラーページのエディタ連携を実用的にする変更です。RAILS_HOST_APP_PATH という1つの環境変数の追加により、コンテナ内部パスとホストパスの差異を吸収し、既存の EDITOR 連携機能をコンテナ環境でも利用可能にしています。後方互換性を維持しながら、現代的なコンテナベース開発フローに対応した実装といえます。