# Ruby on Rails Framework コードリーディングガイドライン

## はじめに

このガイドラインは、Ruby on Railsフレームワーク（バージョン8.2.0.alpha）のコードベースを効率的に理解するための手引きです。
Rubyに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

**このリポジトリの特徴:**
このリポジトリはRuby on Railsフレームワーク自体のソースコードであり、一般的なRailsアプリケーションとは構造が異なります。
フレームワークは複数の独立したコンポーネント（gems）で構成されており、それぞれが独自のディレクトリ構造を持っています。

---

## 1. 言語基礎

> このセクションでは、Rubyの基本構文と概念を解説します。

### 1.1 プログラム構造

Rubyはオブジェクト指向スクリプト言語です。ファイル拡張子は`.rb`を使用します。

```ruby
# ファイル: activesupport/lib/active_support.rb:36-38
module ActiveSupport
  extend ActiveSupport::Autoload
```

Rubyプログラムの基本構造:
- `module`: 名前空間やミックスインを定義
- `class`: クラスを定義
- `def`: メソッドを定義
- `#`: 行コメント
- `#--` / `#++`: ドキュメント生成ツール向けのブロックコメント

### 1.2 データ型と変数

Rubyの主要なデータ型と変数の命名規則:

| 種類 | 記法 | 例 |
|------|------|-----|
| ローカル変数 | snake_case | `user_name`, `callback_sequence` |
| インスタンス変数 | @付き | `@user`, `@_dependencies` |
| クラス変数 | @@付き | `@@callbacks` |
| 定数 | UPPER_SNAKE_CASE | `CALLBACK_FILTER_TYPES`, `ENCODING_FLAG` |
| シンボル | :付き | `:before`, `:after`, `:around` |

```ruby
# ファイル: activesupport/lib/active_support/callbacks.rb:73
CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze
```

### 1.3 制御構造

```ruby
# 条件分岐の例
# ファイル: activesupport/lib/active_support/callbacks.rb:100-103
if callbacks.empty?
  yield if block_given?
else
  env = Filters::Environment.new(self, false, nil)
end

# ループの例
@_dependencies.each { |dep| base.include(dep) }
```

### 1.4 関数/メソッド定義

```ruby
# インスタンスメソッド
# ファイル: activesupport/lib/active_support/callbacks.rb:97
def run_callbacks(kind, type = nil)
  callbacks = __callbacks[kind.to_sym]
  # ...
end

# クラスメソッド
# ファイル: activerecord/lib/active_record.rb:304
def self.global_thread_pool_async_query_executor
  concurrency = global_executor_concurrency || 4
  @global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
    # ...
  )
end
```

### 1.5 モジュール/インポート

Rubyでは`require`でファイルを読み込み、`include`/`extend`でモジュールを取り込みます。

```ruby
# ファイル: activerecord/lib/active_record/base.rb:1-13
require "active_support/benchmarkable"
require "active_support/dependencies"
require "active_support/descendants_tracker"
require "active_support/time"
require "active_support/core_ext/class/subclasses"
require "active_record/log_subscriber"
```

**モジュール取り込みパターン:**

| パターン | 用途 | 例 |
|----------|------|-----|
| `include` | インスタンスメソッドを追加 | `include Core` |
| `extend` | クラスメソッドを追加 | `extend ConnectionHandling` |
| `prepend` | メソッドをオーバーライド（元のメソッドを呼び出し可能） | `prepend Concern` |

---

## 2. プロジェクト固有の概念

> このセクションでは、Railsフレームワーク特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### ActiveSupport::Concern
モジュールの依存関係を管理し、クラスメソッドとインスタンスメソッドを簡潔に定義するためのパターン。

```ruby
# ファイル: activesupport/lib/active_support/concern.rb:27-36
module M
  extend ActiveSupport::Concern

  included do
    scope :disabled, -> { where(disabled: true) }
  end

  class_methods do
    # クラスメソッドを定義
  end
end
```

#### ActiveSupport::Callbacks
オブジェクトのライフサイクルにフックを追加するシステム。`:before`, `:after`, `:around`の3種類のコールバックをサポート。

```ruby
# ファイル: activesupport/lib/active_support/callbacks.rb:36-64
class Record
  include ActiveSupport::Callbacks
  define_callbacks :save

  def save
    run_callbacks :save do
      puts "- save"
    end
  end
end
```

#### Autoload
遅延読み込みを実現するパターン。必要になるまでファイルを読み込まない。

```ruby
# ファイル: activesupport/lib/active_support.rb:39-93
module ActiveSupport
  extend ActiveSupport::Autoload

  autoload :Concern
  autoload :Callbacks

  eager_autoload do
    autoload :Cache
    autoload :Deprecation
  end
end
```

### 2.2 プロジェクト独自のパターン

#### Railtie / Engine / Application 階層
Railsの起動とコンポーネント管理の階層構造:

```
Rails::Railtie (基底クラス)
    └── Rails::Engine (拡張機能を持つRailtie)
        └── Rails::Application (アプリケーション本体)
```

```ruby
# ファイル: railties/lib/rails/railtie.rb:32-35
# Railtieの定義例
module MyGem
  class Railtie < Rails::Railtie
  end
end
```

#### 設定属性の定義パターン
`singleton_class.attr_accessor`を使用して設定オプションを定義:

```ruby
# ファイル: activerecord/lib/active_record.rb:184-186
singleton_class.attr_accessor :disable_prepared_statements
self.disable_prepared_statements = false
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `{component_name}.rb` | コンポーネントのエントリーポイント | `active_support.rb`, `active_record.rb` |
| `{component_name}/` | コンポーネントの詳細実装ディレクトリ | `active_support/`, `active_record/` |
| `{feature}.rb` | 機能モジュール | `callbacks.rb`, `concern.rb` |
| `{concept}.rb` | ドメイン概念 | `base.rb`, `relation.rb` |
| `{adapter}_adapter.rb` | データベースアダプター | `postgresql_adapter.rb` |
| `*_test.rb` | テストファイル | `callbacks_test.rb` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `Base` | 基底クラス | `ActiveRecord::Base`, `ActionController::Base` |
| `Abstract*` | 抽象クラス | `AbstractController`, `AbstractAdapter` |
| `*Methods` | メソッドを提供するモジュール | `AttributeMethods`, `FinderMethods` |
| `*Handler` | 処理を担当するクラス | `FilterAttributeHandler` |
| `*Builder` | オブジェクト構築クラス | `PredicateBuilder`, `FormBuilder` |
| `*Subscriber` | イベント購読クラス | `LogSubscriber`, `StructuredEventSubscriber` |
| `*Adapter` | 外部システムとの接続 | `ConnectionAdapters` |
| `*Wrapper` | ラッパークラス | `ExecutionWrapper` |
| `*Tracker` | 追跡クラス | `DescendantsTracker` |
| `*Reloader` | リロード機能 | `Reloader`, `RoutesReloader` |
| `self.` | クラスメソッド | `self.eager_load!` |
| `_` prefix | プライベート用途 | `@_dependencies`, `@_included_block` |

### 3.3 プログラム分類一覧

| 分類 | 説明 | 配置場所 |
|------|------|---------|
| エントリーポイント | gemのメインファイル | `lib/{gem_name}.rb` |
| コアクラス | 主要機能の実装 | `lib/{gem_name}/` |
| 拡張 | Ruby標準クラスの拡張 | `lib/active_support/core_ext/` |
| テスト | テストコード | `test/` |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
rails-main/
├── actioncable/          # Action Cable - WebSocket統合
├── actionmailbox/        # Action Mailbox - 受信メール処理
├── actionmailer/         # Action Mailer - メール送信
├── actionpack/           # Action Pack - Controller & Routing
├── actiontext/           # Action Text - リッチテキスト
├── actionview/           # Action View - テンプレートレンダリング
├── activejob/            # Active Job - バックグラウンドジョブ
├── activemodel/          # Active Model - モデル抽象化
├── activerecord/         # Active Record - ORM
├── activestorage/        # Active Storage - ファイルアップロード
├── activesupport/        # Active Support - ユーティリティ
├── railties/             # Railties - フレームワーク統合
├── guides/               # ドキュメント
├── tools/                # 開発ツール
├── Gemfile               # 依存関係定義
├── Rakefile              # タスク定義
└── rails.gemspec         # gem仕様
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `activesupport/` | Ruby拡張・ユーティリティ | `lib/active_support.rb`, `lib/active_support/concern.rb` |
| `activerecord/` | データベースORM | `lib/active_record/base.rb`, `lib/active_record/relation.rb` |
| `actionpack/` | コントローラー・ルーティング | `lib/action_controller.rb`, `lib/action_dispatch.rb` |
| `actionview/` | ビュー・テンプレート | `lib/action_view.rb`, `lib/action_view/template.rb` |
| `railties/` | フレームワーク起動・統合 | `lib/rails/railtie.rb`, `lib/rails/application.rb` |

### 各gemの内部構造

各gemは以下の共通構造を持ちます:

```
{gem_name}/
├── lib/
│   ├── {gem_name}.rb          # エントリーポイント
│   └── {gem_name}/            # 詳細実装
│       ├── base.rb            # 基底クラス（存在する場合）
│       ├── version.rb         # バージョン情報
│       └── ...                # その他機能
├── test/                      # テストコード
├── {gem_name}.gemspec         # gem仕様
├── Rakefile                   # タスク定義
├── README.rdoc/md             # ドキュメント
└── CHANGELOG.md               # 変更履歴
```

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Ruby on Railsは**MVC（Model-View-Controller）**パターンを採用したフルスタックWebフレームワークです。

```mermaid
graph TD
    subgraph "Railties"
        App[Rails::Application]
        Engine[Rails::Engine]
        Railtie[Rails::Railtie]
    end

    subgraph "MVC Layer"
        AR[Active Record - Model]
        AV[Action View - View]
        AP[Action Pack - Controller]
    end

    subgraph "Support Layer"
        AS[Active Support]
        AM[Active Model]
    end

    subgraph "Additional Features"
        AJ[Active Job]
        AC[Action Cable]
        ASt[Active Storage]
        AT[Action Text]
        AMa[Action Mailer]
        AMb[Action Mailbox]
    end

    App --> Engine --> Railtie
    AR --> AS
    AR --> AM
    AV --> AS
    AP --> AS
    AP --> AV
    AJ --> AS
    AC --> AS
    ASt --> AR
    AT --> AR
    AMa --> AS
    AMb --> AS
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Application | アプリケーション起動・設定 | `railties/lib/rails/application.rb` |
| Controller | HTTPリクエスト処理 | `actionpack/lib/action_controller/base.rb` |
| View | テンプレートレンダリング | `actionview/lib/action_view/base.rb` |
| Model | ビジネスロジック・データアクセス | `activerecord/lib/active_record/base.rb` |
| Support | 共通ユーティリティ | `activesupport/lib/active_support.rb` |

### 5.3 データフロー

```
HTTP Request
    ↓
Rack Middleware Stack
    ↓
Action Dispatch (Routing)
    ↓
Action Controller
    ↓
Active Record (Database)
    ↓
Action View (Template)
    ↓
HTTP Response
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

各gemのエントリーポイントは`lib/{gem_name}.rb`に配置されています。

```ruby
# ファイル: activesupport/lib/active_support.rb:36-93
module ActiveSupport
  extend ActiveSupport::Autoload

  autoload :Concern
  autoload :Callbacks
  # ... その他のautoload定義

  def self.eager_load!
    super
    NumberHelper.eager_load!
  end
end
```

### 6.2 ビジネスロジック

**Active Record::Base** がモデル層の中心です。

```ruby
# ファイル: activerecord/lib/active_record/base.rb:282-334
class Base
  include ActiveModel::API

  extend ActiveSupport::Benchmarkable
  extend ActiveSupport::DescendantsTracker
  extend ConnectionHandling

  include Core
  include Persistence
  include Validations
  include Associations
  # ... 多くのモジュールをinclude
end
```

### 6.3 データアクセス

Active Recordの接続管理とクエリ実行:

```ruby
# ファイル: activerecord/lib/active_record.rb:569-572
def self.disconnect_all!
  ConnectionAdapters::PoolConfig.disconnect_all!
end
```

### 6.4 ユーティリティ/共通機能

**Active Support** が共通ユーティリティを提供:

```ruby
# ファイル: activesupport/lib/active_support.rb:63-93
eager_autoload do
  autoload :BacktraceCleaner
  autoload :Benchmark
  autoload :Cache
  autoload :Callbacks
  autoload :Deprecation
  autoload :Inflector
  autoload :JSON
  # ...
end
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Concern | モジュールの依存関係管理 | 高 | `activesupport/lib/active_support/concern.rb` |
| Callbacks | ライフサイクルフック | 高 | `activesupport/lib/active_support/callbacks.rb` |
| Autoload | 遅延読み込み | 高 | 全gemのエントリーポイント |
| Module Inclusion | モジュールの段階的取り込み | 高 | `activerecord/lib/active_record/base.rb` |
| Configuration | 設定値の管理 | 中 | `activerecord/lib/active_record.rb` |

### 各パターンの詳細

#### パターン1: Concern

**目的:** モジュールの依存関係を適切に解決し、`included`ブロックと`class_methods`ブロックで簡潔にコードを整理する。

**実装例:**
```ruby
# ファイル: activesupport/lib/active_support/concern.rb:112-140
module Concern
  def self.extended(base)
    base.instance_variable_set(:@_dependencies, [])
  end

  def append_features(base)
    if base.instance_variable_defined?(:@_dependencies)
      base.instance_variable_get(:@_dependencies) << self
      false
    else
      return false if base < self
      @_dependencies.each { |dep| base.include(dep) }
      super
      base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
      base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
    end
  end
end
```

**解説:** `append_features`をオーバーライドし、依存モジュールを自動的にincludeし、ClassMethodsを自動的にextendする。

#### パターン2: Callbacks

**目的:** オブジェクトのライフサイクル（save, validate等）にフックを追加可能にする。

**実装例:**
```ruby
# ファイル: activesupport/lib/active_support/callbacks.rb:97-144
def run_callbacks(kind, type = nil)
  callbacks = __callbacks[kind.to_sym]

  if callbacks.empty?
    yield if block_given?
  else
    env = Filters::Environment.new(self, false, nil)
    next_sequence = callbacks.compile(type)

    if next_sequence.final?
      next_sequence.invoke_before(env)
      env.value = !env.halted && (!block_given? || yield)
      next_sequence.invoke_after(env)
      env.value
    else
      # around callbacks handling...
    end
  end
end
```

**解説:** before/after/aroundの3種類のコールバックを順序通りに実行する。

#### パターン3: Module Inclusion Stack

**目的:** 複数のモジュールを段階的にincludeし、機能を追加する。

**実装例:**
```ruby
# ファイル: activerecord/lib/active_record/base.rb:299-331
class Base
  include ActiveModel::API

  include Core
  include Persistence
  include ReadonlyAttributes
  include ModelSchema
  include Inheritance
  include Scoping
  include Sanitization
  include AttributeAssignment
  include Integration
  include Validations
  include CounterCache
  include Attributes
  include Locking::Optimistic
  include Locking::Pessimistic
  include Callbacks
  include Associations
  # ...
end
```

**解説:** 各モジュールが特定の機能を提供し、Baseクラスはそれらを全て統合する。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: ActiveRecord モデルの保存フロー

**概要:** モデルインスタンスの`save`メソッド呼び出しからデータベース保存までの流れ

**処理フロー:**
```
Model#save → run_callbacks(:save) → Persistence#create_or_update → ConnectionAdapters → Database
```

**詳細な追跡:**

1. **saveメソッドの呼び出し** (`activerecord/lib/active_record/persistence.rb`)

   Persistenceモジュールの`save`メソッドが呼ばれる。

2. **コールバックの実行** (`activesupport/lib/active_support/callbacks.rb:97`)
   ```ruby
   def run_callbacks(kind, type = nil)
     callbacks = __callbacks[kind.to_sym]
     # before_save, around_save, after_save が実行される
   end
   ```

3. **Validationの実行**

   Validationsモジュールがincludeされているため、バリデーションが実行される。

4. **データベースへの書き込み**

   ConnectionAdaptersを通じてSQLが発行される。

#### 例2: Railsアプリケーション起動フロー

**概要:** Railsアプリケーションの起動プロセス

**処理フロー:**
```
config/application.rb → Rails::Application.inherited → run_load_hooks → initializers
```

**詳細な追跡:**

1. **Applicationクラスの継承** (`railties/lib/rails/application.rb:72-78`)
   ```ruby
   def inherited(base)
     super
     Rails.app_class = base
     add_lib_to_load_path!(find_root(base.called_from))
     ActiveSupport.run_load_hooks(:before_configuration, base)
   end
   ```

2. **インスタンス初期化** (`railties/lib/rails/application.rb:110-134`)
   ```ruby
   def initialize(initial_variable_values = {}, &block)
     super()
     @initialized = false
     @reloaders = []
     @executor = Class.new(ActiveSupport::Executor)
     @reloader = Class.new(ActiveSupport::Reloader)
     @autoloaders = Rails::Autoloaders.new
   end
   ```

3. **Initializerの実行**

   各Railtieが登録したinitializerが順番に実行される。

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `rails.gemspec` - 依存関係の理解
3. `railties/lib/rails/application.rb` - アプリケーション起動の理解

#### 特定機能を理解したい場合
1. 対象gemの`README.rdoc`
2. `lib/{gem_name}.rb` - エントリーポイント
3. `lib/{gem_name}/base.rb` - 基底クラス（存在する場合）

#### 改修作業を行う場合
1. 対象機能のテストファイル（`test/`以下）
2. 対象機能の実装ファイル
3. `CHANGELOG.md` - 変更履歴の確認

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト全体の説明 | 最初に参照 |
| `CONTRIBUTING.md` | コントリビューション方法 | 開発開始前 |
| `RELEASING_RAILS.md` | リリースプロセス | リリース時 |
| `{gem}/README.rdoc` | 各gemの説明 | 特定gem理解時 |
| `{gem}/CHANGELOG.md` | 変更履歴 | バージョン間差異確認時 |
| `guides/` | 詳細ガイド | 深い理解が必要な時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `autoload`と`require`の違いは？
A: `require`は即座にファイルを読み込みますが、`autoload`は定数が参照された時点で初めて読み込みます。Railsでは起動時間短縮のため`autoload`を多用しています。

#### Q: `extend`と`include`の違いは？
A: `include`はインスタンスメソッドを追加し、`extend`はクラスメソッドを追加します。

```ruby
module M
  def foo; end
end

class A
  include M  # A.new.foo が使える
end

class B
  extend M   # B.foo が使える
end
```

#### Q: `singleton_class.attr_accessor`とは？
A: クラス自体の属性（クラスメソッドでアクセス可能な属性）を定義します。設定値の管理によく使われます。

```ruby
singleton_class.attr_accessor :disable_prepared_statements
self.disable_prepared_statements = false
# ActiveRecord.disable_prepared_statements でアクセス可能
```

#### Q: `frozen_string_literal: true`とは？
A: ファイル内の文字列リテラルを全て凍結（immutable）にするマジックコメントです。メモリ効率と安全性が向上します。

### デバッグのヒント

1. **メソッド定義元を確認**: `method(:method_name).source_location`
2. **継承階層を確認**: `Class.ancestors`
3. **includeされたモジュールを確認**: `Class.included_modules`
4. **クラスメソッドを確認**: `Class.methods(false)`
5. **インスタンスメソッドを確認**: `Class.instance_methods(false)`

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| Railtie | Railsフレームワークを拡張するための基本単位 |
| Engine | 独立した機能を持つRailtie |
| Concern | モジュールの依存関係を管理するパターン |
| Callback | ライフサイクルイベントへのフック |
| Autoload | 遅延読み込み機構 |
| Gem | Rubyのパッケージ管理単位 |
| Middleware | リクエスト/レスポンスを処理するチェーン |
| Rack | Ruby Webサーバーインターフェース |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `activesupport/` | Active Support gem | ユーティリティ、拡張 |
| `activerecord/` | Active Record gem | ORM、データベースアクセス |
| `actionpack/` | Action Pack gem | Controller、Routing |
| `actionview/` | Action View gem | テンプレート、ヘルパー |
| `railties/` | Railties gem | フレームワーク統合 |
| `Gemfile` | 依存関係定義 | 開発用gem |
| `rails.gemspec` | gem仕様 | 本番用依存関係 |

### C. 参考資料

- [Ruby on Rails Guides](https://guides.rubyonrails.org)
- [Ruby on Rails API Documentation](https://api.rubyonrails.org)
- [Ruby Documentation](https://ruby-doc.org)
- [RubyGems](https://rubygems.org)
