「Rails界の教科書」をAIに教え込む
37signals(BasecampやHEYを作った会社)のコードを分析して作られた「Unofficial 37signals Coding Style Guide」が公開され、話題になっています。
このガイドの本当の価値は、単なる「読み物」ではありません。Claude SkillsやCursorの指示書として使えることにあります。
つまり、DHH(Ruby on Rails創設者)直伝の開発哲学をAIに教え込み、正統派Railsコードを自動生成させることができるのです。
Unofficial 37signals Coding Style Guideとは
Marc Köhlbrugge氏が作成したこのガイドは、37signalsの内部アプリ「Fizzy」の265個のPull RequestをClaudeに分析させて生成されました。
| 項目 | 内容 |
|---|---|
| 作成者 | Marc Köhlbrugge氏 |
| 分析対象 | 37signals Fizzyアプリの265 PR |
| 生成方法 | Claude AIによるPR分析 |
| ファイル数 | 37個のMarkdownファイル |
| カバー領域 | Controllers、Models、Stimulus、CSS、認証、テストなど |
| GitHub Stars | 222+ |
なぜ37signalsのコードが重要なのか
37signalsはRuby on Railsの「本家」です。DHHが実際に使っているパターンは、Railsの設計思想そのものを反映しています。
このガイドを使えば:
- 「Railsらしい」コードの書き方を学べる
- フレームワークの意図に沿った設計ができる
- 余計なgem依存を避けた軽量な実装ができる
37signalsの8つの開発哲学
このガイドが伝える核心的な原則です。
| 原則 | 内容 | 従来のアプローチとの違い |
|---|---|---|
| Rich Domain Models | モデルにロジックを集約 | Service Objectを乱用しない |
| CRUD Controllers | 標準アクションに徹する | カスタムアクションを避ける |
| Concerns | 横断的なコード共有 | 継承よりコンポジション |
| Records as State | 状態をレコードで表現 | boolean列を避ける |
| Database-backed | DBに寄せる | Redisを使わない |
| Build it yourself | 自作を優先 | gemを安易に追加しない |
| Ship to learn | プロトタイプで出荷 | 完璧を求めすぎない |
| Vanilla Rails | フレームワーク機能を活用 | 独自実装を避ける |
具体的なパターン例
1. Controllerパターン:薄いコントローラー
37signalsのControllerは「オーケストレーター」に徹します。ビジネスロジックはモデルに委譲。
良い例:
def create
@card.close # ロジックはモデルにカプセル化
respond_to do |format|
format.turbo_stream { render_card_replacement }
end
end
悪い例(避けるべき):
def create
# コントローラーにトランザクション、イベント作成、通知処理が全部入っている
ActiveRecord::Base.transaction do
@card.update!(closed: true)
Event.create!(card: @card, action: 'closed')
NotificationJob.perform_later(@card)
end
end
2. Modelパターン:状態をレコードで表現
boolean列の代わりに専用のレコードを作成します。
従来のアプローチ:
# cards テーブル
# - closed: boolean
# - closed_at: datetime
# - closed_by_id: integer
card.update!(closed: true, closed_at: Time.current, closed_by: current_user)
37signalsアプローチ:
# closures テーブル(カードとは別)
# - card_id: integer
# - created_at: datetime(いつ閉じたか)
# - creator_id: integer(誰が閉じたか)
card.closures.create!(creator: current_user)
# クエリも直感的
Card.joins(:closure) # 閉じたカード
Card.where.missing(:closure) # 開いているカード
この方法のメリット:
- 履歴の自動記録:created_atで「いつ」がわかる
- 帰属の明確化:creator_idで「誰が」がわかる
- 効率的なクエリ:joinsとwhere.missingで簡潔に
3. Concernパターン:コンポーザブルな振る舞い
37signalsのCardモデルは多数のConcernsで構成されています:
class Card
各Concernは50-150行に収め、単一の責務を持ちます。
4. Stimulusパターン:単一目的のコントローラー
37signalsのStimulusコントローラーは3つの原則に従います:
- Single-purpose:1つのコントローラーに1つの仕事
- Configured via values:ハードコードせず値で設定
- Event-based communication:直接呼び出しではなくイベントで通信
例:Auto-Submit Controller
// デバウンス付き自動送信
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = { delay: { type: Number, default: 300 } }
submit() {
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.element.requestSubmit()
}, this.delayValue)
}
disconnect() {
clearTimeout(this.timeout) // クリーンアップ必須
}
}
Claude Skillsとしての活用方法
このガイドの真価は、AIコーディングの指示書として使えることにあります。
セットアップ方法
方法1:CLAUDE.mdをプロジェクトに配置
# リポジトリをクローン
git clone https://github.com/marckohlbrugge/unofficial-37signals-coding-style-guide
# CLAUDE.mdと必要なファイルをプロジェクトにコピー
cp unofficial-37signals-coding-style-guide/CLAUDE.md your-rails-project/
cp unofficial-37signals-coding-style-guide/controllers.md your-rails-project/docs/
cp unofficial-37signals-coding-style-guide/models.md your-rails-project/docs/
方法2:Agent Skillsとして構成
your-rails-project/
├── .claude/
│ └── skills/
│ └── 37signals-rails/
│ ├── SKILL.md # メイン指示
│ ├── controllers.md # コントローラーパターン
│ ├── models.md # モデルパターン
│ ├── stimulus.md # フロントエンド
│ └── testing.md # テスト規約
└── app/
└── ...
SKILL.mdの書き方例
---
name: 37signals-rails-style
description: 37signalsスタイルでRailsコードを生成します。Railsのコントローラー、モデル、Stimulus作成時に使用。
---
# 37signals Rails Style Guide
## 基本原則
1. **Rich Domain Models** - Service Objectよりモデルにロジック
2. **CRUD Controllers** - 標準アクションのみ使用
3. **Records as State** - boolean列より状態レコード
4. **Concerns** - 横断的機能はConcernで実装
## 詳細ガイド
- コントローラー: [controllers.md](controllers.md)
- モデル: [models.md](models.md)
- フロントエンド: [stimulus.md](stimulus.md)
実際の使用例
Before:AIに何も指示しない場合
「Cardモデルにクローズ機能を追加して」と依頼すると:
# AIが生成する典型的なコード
class Card
After:37signals Skillを使用した場合
同じ依頼でも、Skillがあると:
# Closureモデルを作成
class Closure { where.missing(:closure) }
scope :closed, -> { joins(:closure) }
end
def close(by:)
create_closure!(creator: by)
end
def reopen
closure&.destroy
end
def closed?
closure.present?
end
end
自分のプロジェクト用Skillを作る方法
37signalsガイドと同じ手法で、自社のコードベースからスタイルガイドを抽出できます。
ステップ1:PRを分析させる
プロンプト例: 「以下のPRの内容から、コーディングパターンと設計判断を抽出してください。 転用可能なパターンのみを含め、ビジネスロジック固有の部分は除外してください。」
ステップ2:パターンをカテゴリ分け
- コントローラー規約
- モデル設計
- フロントエンド(Stimulus/CSS)
- テスト規約
- インフラ・デプロイ
ステップ3:SKILL.md形式に整理
---
name: my-company-rails-style
description: 自社Railsプロジェクトのコーディング規約。新機能開発時に使用。
---
# My Company Rails Style
## 原則
[PRから抽出したパターンを記載]
## 詳細
- [controllers.md](controllers.md)
- [models.md](models.md)
注意点と限界
このガイドには重要な注意点があります。
⚠️ 「このガイドはLLM(Claude)がPRの説明とコードスニペットを分析して生成したものです。ハルシネーションや不正確さが含まれる可能性があります。実際の実装と照らし合わせて検証してください。」
– README.mdより
検証のポイント
- 重要なパターンは実際のFizzyコードで確認
- プロジェクトに適用前に小規模でテスト
- チームで合意を取ってから導入
まとめ:AIコーディングの新しい形
「Unofficial 37signals Coding Style Guide」が示すのは、AIコーディングの新しいパラダイムです。
- PRを分析 → スタイルガイド生成:実際のコードからパターンを抽出
- SKILL.md形式で配布:Claude/Cursor/VS Codeで共通利用
- AIに「流派」を教える:一貫したスタイルのコードを自動生成
Rails開発者にとって、37signalsのコードは「お手本」そのものです。このガイドをAgent Skillsとして活用することで、DHH直伝の開発哲学をAIに教え込み、正統派Railsコードを効率的に生成できるようになります。
まずは試しに、プロジェクトにCLAUDE.mdを配置してみてください。AIの出力品質が変わることを実感できるはずです。
関連リンク:
関連記事:


コメント