AI Session Notes - 2026-03-20
Railsにおけるレイヤードアーキテクチャとデザインパターン
学んだこと
- Rails の Convention over Configuration がカバーするのは MVC の基本構造・ファイル配置・命名規則・ActiveRecord のパターンまで。Service Object、Query Object、Finder、Prioritizer のようなレイヤー分けは Rails の規約の外 にある
- これらのパターンは OOP 設計原則(特に単一責任原則)、GoF デザインパターン、Rails コミュニティの暗黙知、チーム独自の規約から来ている
- Rails で頻出する設計パターンは限られており、以下の 6〜7 パターンを押さえれば大半のケースに対応できる:
- Service Object — ユースケースの実行
- Query Object — 複雑な DB クエリの組み立て
- Finder — 検索条件の組み立て
- Form Object — 複数モデルにまたがるバリデーション
- Decorator / Presenter — 表示用ロジック
- Policy — 認可ロジック
詳細
GoF デザインパターンと Rails パターンの関係
GoF の 23 パターン(『Java言語で学ぶデザインパターン入門』等で学べるもの)のうち、Rails で日常的に使うのは一部に限られる:
- Template Method — ActiveRecord のコールバックの仕組み
- Strategy — アルゴリズムの切り替え(例: ソート・優先度付けロジックの差し替え)
- Observer —
after_commit等のコールバック機構 - Command — Service Object の考え方に近い
- Decorator — Presenter / Decorator パターン
一方、Query Object や Form Object は GoF にはない Web アプリ / Rails 特有のパターン。GoF の本で OOP の「考え方」を身につけた上で、Rails での「適用の仕方」を別途補うのが効率的。
学習リソース
- Ruby Science(thoughtbot) — Rails での設計パターンを具体的に解説。無料で読める
- Practical Object-Oriented Design in Ruby(POODR)(Sandi Metz) — Ruby での OOP 設計の定番書
- Sustainable Web Development with Ruby on Rails(David Copeland)
- Fearless Refactoring: Rails Controllers(Arkency)
Docker をランタイムとして使う(ボリュームマウント方式)
学んだこと
- Docker コンテナにローカルのソースコードをボリュームマウントすれば、イメージを再ビルドせずにコードの変更を即座に反映して実行できる
- インタープリタ言語(Ruby, Python 等)はそのまま実行可能。コンパイル言語(Java 等)もコンテナ内でコンパイル&実行すればローカルに開発ツールをインストールする必要がない
- 言語ごとにコンテナを分ける構成なら
docker-compose.ymlで複数サービスを定義し、共通の実行スクリプトで使い分けられる
詳細
# docker-compose.yml
services:
java:
image: eclipse-temurin:17
volumes:
- ./java:/app
working_dir: /app
ruby:
image: ruby:3.3
volumes:
- ./ruby:/app
working_dir: /app
注意点として、コンパイル言語ではビルド生成物(.class 等)がボリュームマウント経由でローカルにも残るため、.gitignore への追加が必要。
日本語ディレクトリ名と URL のパーセントエンコーディング
学んだこと
- Git や MkDocs は日本語ディレクトリ名・ファイル名を問題なく扱える
- ただし Web サイトの URL では日本語がパーセントエンコードされる(例:
Books/%E6%9B%B8%E7%B1%8D%E5%90%8D/) - ブラウザのアドレスバーでは日本語表示されることが多いが、リンクのコピペではエンコード済みの長い文字列になる
- 個人用途やチーム内利用ではわかりやすさ優先で日本語名のままでも問題ない
学習リポジトリの分離戦略
学んだこと
- 「学んだこと(メモ・気づき)」と「動くコード(実装・実行環境)」はリポジトリを分けると管理しやすい
- メモ側から実装リポジトリへリンクを貼ることで、相互に導線を確保できる
- Docker 設定やテストコードが増えると、学習メモのリポジトリの趣旨がぼやけるため、コードが主体になるなら別リポジトリにする判断基準が有効
シェルスクリプト: ファイルパスからパラメータを推論する
学んだこと
- CLI ツールの引数設計で、ファイルパスのディレクトリ構造から暗黙的にパラメータを推論できる場合がある
- 例:
./run java/iterator/Main.javaのパス先頭java/から言語を自動判定すれば、./run java java/iterator/Main.javaのように言語を2回指定する冗長さを排除できる - Bash でのパス分解:
${filepath%%/*}で先頭ディレクトリ、${filepath#"$lang/"}で残りのパスを取得できる
Claude Code v2.1.80: statusline への rate_limits フィールド追加
学んだこと
- Claude Code の statusline スクリプトは、stdin に JSON データがパイプで渡される仕組み。スクリプトの stdout がステータスバーに表示される
- v2.1.80 で stdin JSON に
rate_limitsフィールドが追加され、レート制限情報(5時間/7日ウィンドウ)をネイティブに取得できるようになった - これ以前はレート制限を表示するために、macOS Keychain から OAuth トークンを抽出 → API エンドポイントに直接 HTTP リクエスト → レスポンスをキャッシュ管理、というワークアラウンドが必要だった
- 公式対応により、
jqで stdin JSON から読み取るだけでよくなり、スクリプトが大幅に簡素化できる
詳細
rate_limits の JSON 構造
{
"rate_limits": {
"five_hour": {
"used_percentage": 2,
"resets_at": 1773997200
},
"seven_day": {
"used_percentage": 3,
"resets_at": 1774040400
}
}
}
注意点:
- キー名は
five_hour/seven_day(session/weeklyではない) resets_atは Unix タイムスタンプ(秒)であり、ISO 8601 文字列ではない- リリースノートやサードパーティの解説だけでは正確なフィールド名・型がわからないことがある。stdin JSON をファイルにダンプして実際の構造を確認するデバッグ手法が有効
statusline スクリプトでの読み取り例
input=$(cat)
FIVE_PCT=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
FIVE_RESET=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
# resets_at は Unix タイムスタンプなので date -r で変換
FIVE_RESET_FMT=$(TZ=Asia/Tokyo date -r "$FIVE_RESET" "+%-I%p")
メタ情報
- ツール: Claude Code
- 関連技術: Ruby on Rails, デザインパターン, OOP設計原則, Docker, MkDocs, シェルスクリプト, Claude Code statusline