# 画面設計書 11-アクション未定義画面

## 概要

本ドキュメントは、Ruby on Railsフレームワークにおける「アクション未定義画面」の設計仕様を定義する。コントローラーに存在しないアクションへのリクエストが発生した際に表示される開発者向けエラー診断画面である。

### 本画面の処理概要

この画面は、Railsアプリケーションの開発中に、存在しないコントローラーアクションにアクセスした際に表示されるエラー診断画面である。開発者がルーティングやコントローラーの設定ミスを迅速に特定・修正できるよう、詳細なエラー情報と修正候補を提供する。

**業務上の目的・背景**：Railsアプリケーション開発において、ルーティング定義とコントローラーアクションの不整合は頻繁に発生する問題である。この画面は、開発者がそのような問題を素早く発見し、修正するためのフィードバックを提供することで、開発効率の向上に寄与する。本番環境ではセキュリティ上の理由から詳細情報は表示されず、シンプルな404エラーページに置き換えられる。

**画面へのアクセス方法**：開発環境において、ルーティングで定義されているがコントローラーに対応するアクションメソッドが存在しないURLにアクセスした際に、自動的にこの画面が表示される。例えば、`routes.rb`で`get '/users/:id' => 'users#show'`と定義されているが、`UsersController`に`show`メソッドが存在しない場合に表示される。

**主要な操作・処理内容**：
1. エラーメッセージの表示 - 存在しないアクション名と対象コントローラーを明示
2. 修正候補の提示 - `did_you_mean` gemによる類似アクション名の提案（利用可能な場合）
3. クリップボードコピー機能 - エラー情報をクリップボードにコピーしてIssue報告等に活用
4. 例外情報の確認 - AbstractController::ActionNotFound例外の詳細情報を表示

**画面遷移**：
- 遷移元：存在しないアクションへのHTTPリクエスト（任意のHTTPメソッド）
- 遷移先：なし（エラー画面のため、修正後に再度リクエストを実行）

**権限による表示制御**：
- 開発環境（`config.consider_all_requests_local = true`）でのみ詳細情報が表示される
- 本番環境では、この画面は表示されず、`public/404.html`またはカスタムエラーページにリダイレクトされる

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | Debug Exceptions | 主機能 | UnknownAction例外の捕捉・表示処理 |
| 7 | Action Controller | 補助機能 | アクション候補の提案表示 |

## 画面種別

エラー診断（開発環境専用）

## URL/ルーティング

特定のURLは存在しない。存在しないアクションへのリクエスト時に、DebugExceptionsミドルウェアが例外を捕捉して本画面を表示する。

例：
- `GET /users/show` - UsersController#showが未定義の場合
- `POST /articles/create` - ArticlesController#createが未定義の場合

## 入出力項目

本画面はエラー診断画面のため、ユーザー入力項目は存在しない。

| 項目 | 入出力 | 説明 |
|------|--------|------|
| なし | - | ユーザー入力を受け付けない |

## 表示項目

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| ヘッダータイトル | String | "Unknown action" 固定文字列 | テンプレート固定値 |
| エラーメッセージ | String | 存在しないアクション名を含むエラーメッセージ | `@exception.message` |
| 修正候補 | Array | 類似アクション名の候補リスト（did_you_mean利用時） | `@exception.corrections` |
| コピーボタン | HTML | エラー情報をクリップボードにコピー | `_copy_button` パーシャル |

## イベント仕様

### 1-コピーボタン押下

**処理内容**：画面に表示されているエラー情報をクリップボードにコピーする。

**トリガー**：コピーボタンクリック

**処理フロー**：
1. JavaScriptがエラーメッセージとスタックトレースをテキストとして取得
2. `navigator.clipboard.writeText()`を使用してクリップボードにコピー
3. ユーザーに視覚的フィードバックを表示

**画面遷移**：なし（同一画面に留まる）

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | なし | なし | 本画面はデータベースへの操作を行わない |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG-001 | エラー | "Unknown action" | 常時ヘッダーに表示 |
| MSG-002 | エラー | "The action '{action}' could not be found for {Controller}" | AbstractController::ActionNotFound発生時 |
| MSG-003 | 情報 | "Did you mean?" + 候補リスト | did_you_mean gemが有効で候補がある場合 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|---------|---------|
| AbstractController::ActionNotFound | コントローラーに対応するアクションメソッドが存在しない | 本画面を表示（開発環境）/404レスポンス（本番環境） |

## 備考

- `did_you_mean` gemがインストールされている場合、類似のアクション名が修正候補として提示される
- この画面はRailsのDebugExceptionsミドルウェアによって生成される
- HTTPステータスコード404（Not Found）で応答する
- XHRリクエストの場合は、HTMLではなくプレーンテキスト形式でレスポンスを返す

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、例外処理の仕組みとExceptionWrapperクラスの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | exception_wrapper.rb | `actionpack/lib/action_dispatch/middleware/exception_wrapper.rb` | ExceptionWrapperクラスの構造、rescue_templatesマッピング、has_corrections?メソッド |

**読解のコツ**: 31-38行目の`rescue_templates`ハッシュで、例外クラス名と表示するテンプレートのマッピングを確認する。`AbstractController::ActionNotFound`が`unknown_action`テンプレートにマッピングされていることを確認。

#### Step 2: エントリーポイントを理解する

処理の起点となるDebugExceptionsミドルウェアを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | ミドルウェアのcallメソッド、例外捕捉の流れ |

**主要処理フロー**:
1. **30-47行目**: `call`メソッドで例外をキャッチし、`render_exception`を呼び出す
2. **58-78行目**: `render_exception`でブラウザ用/API用の分岐処理
3. **80-95行目**: `render_for_browser_request`でテンプレートを使用したHTML生成
4. **121-135行目**: `create_template`でDebugViewを作成し、例外情報を渡す

#### Step 3: テンプレート構造を理解する

エラー画面のテンプレートとパーシャルの関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | unknown_action.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb` | メインテンプレート構造、パーシャルの呼び出し |
| 3-2 | _message_and_suggestions.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb` | エラーメッセージと修正候補の表示ロジック |
| 3-3 | _copy_button.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb` | コピーボタンの実装 |

**主要処理フロー**:
- **1-7行目（unknown_action.html.erb）**: シンプルな構造で、ヘッダーとコピーボタン、メッセージパーシャルを表示
- **1-22行目（_message_and_suggestions.html.erb）**: `has_corrections?`で修正候補の有無を判定し、条件分岐で表示

### プログラム呼び出し階層図

```
HTTPリクエスト
    │
    ├─ DebugExceptions#call（middleware/debug_exceptions.rb:30）
    │      │
    │      ├─ @app.call(env) - 通常のアプリケーション処理
    │      │      └─ AbstractController::ActionNotFound 発生
    │      │
    │      ├─ ExceptionWrapper.new（exception_wrapper.rb:51）
    │      │      └─ rescue_template → "unknown_action"
    │      │
    │      └─ render_exception（debug_exceptions.rb:58）
    │             │
    │             └─ render_for_browser_request（debug_exceptions.rb:80）
    │                    │
    │                    ├─ create_template（debug_exceptions.rb:121）
    │                    │      └─ DebugView.new
    │                    │
    │                    └─ template.render
    │                           └─ rescues/unknown_action.html.erb
    │                                  │
    │                                  ├─ _copy_button.html.erb
    │                                  └─ _message_and_suggestions.html.erb
    │
    └─ HTTPレスポンス（404 Not Found）
```

### データフロー図

```
[入力]                    [処理]                              [出力]

HTTPリクエスト ───────▶ DebugExceptions
   (存在しない                  │
    アクションへ)               ▼
                         AbstractController::ActionNotFound
                                │
                                ▼
                         ExceptionWrapper
                           - rescue_template: "unknown_action"
                           - message: エラーメッセージ
                           - corrections: 修正候補
                                │
                                ▼
                         DebugView
                           - @exception_wrapper
                           - @exception
                                │
                                ▼
                         unknown_action.html.erb ───────▶ HTMLレスポンス
                                                           (404 Not Found)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| debug_exceptions.rb | `actionpack/lib/action_dispatch/middleware/debug_exceptions.rb` | ソース | 例外捕捉・エラー画面生成ミドルウェア |
| exception_wrapper.rb | `actionpack/lib/action_dispatch/middleware/exception_wrapper.rb` | ソース | 例外情報のラッパークラス |
| unknown_action.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb` | テンプレート | アクション未定義エラー画面のメインテンプレート |
| _message_and_suggestions.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb` | テンプレート | エラーメッセージと修正候補表示パーシャル |
| _copy_button.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb` | テンプレート | コピーボタンパーシャル |
| layout.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb` | テンプレート | エラー画面共通レイアウト |
