dhh-rails-style
DHH氏が提唱する37signals流のRuby/Rails開発スタイルに基づき、RESTの原則やHotwireパターンを取り入れ、明瞭さを重視したコードを生成・レビューするSkill。
📜 元の英語説明(参考)
This skill should be used when writing Ruby and Rails code in DHH's distinctive 37signals style. It applies when writing Ruby code, Rails applications, creating models, controllers, or any Ruby file. Triggers on Ruby/Rails code generation, refactoring requests, code review, or when the user mentions DHH, 37signals, Basecamp, HEY, or Campfire style. Embodies REST purity, fat models, thin controllers, Current attributes, Hotwire patterns, and the "clarity over cleverness" philosophy.
🇯🇵 日本人クリエイター向け解説
DHH氏が提唱する37signals流のRuby/Rails開発スタイルに基づき、RESTの原則やHotwireパターンを取り入れ、明瞭さを重視したコードを生成・レビューするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-17
- 取得日時
- 2026-05-17
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[スキル名] dhh-rails-style
<objective> RubyおよびRailsコードに37signals/DHH Railsの慣習を適用します。このスキルは、本番環境の37signalsコードベース(Fizzy/Campfire)とDHHのコードレビューパターンを分析して抽出された、包括的なドメイン専門知識を提供します。 </objective>
<essential_principles>
コア哲学
「最高のコードとは、書かないコードである。次に良いコードは、明らかに正しいコードである。」
バニラRailsで十分です:
- サービスオブジェクトよりもリッチなドメインモデル
- カスタムアクションよりもCRUDコントローラー
- 水平的なコード共有のためのConcern
- 真偽値カラムの代わりにレコードを状態として使用
- すべてをデータベースでバックアップ(Redisなし)
- Gemに手を出す前にソリューションを構築
意図的に避けているもの:
- devise(代わりにカスタムの約150行の認証)
- pundit/cancancan(モデル内のシンプルなロールチェック)
- sidekiq(Solid Queueはデータベースを使用)
- redis(すべてデータベース)
- view_component(パーシャルで十分)
- GraphQL(Turboで十分なREST)
- factory_bot(フィクスチャの方がシンプル)
- rspec(MinitestはRailsに同梱)
- Tailwind(レイヤー付きのネイティブCSS)
開発哲学:
- 出荷、検証、改善 - プロトタイプ品質のコードを本番に投入して学ぶ
- 症状ではなく根本原因を修正する
- 読み取り時の計算よりも書き込み時の操作
- ActiveRecordのバリデーションよりもデータベース制約 </essential_principles>
<intake> 何に取り組んでいますか?
- コントローラー - RESTマッピング、Concern、Turboレスポンス、APIパターン
- モデル - Concern、状態レコード、コールバック、スコープ、PORO
- ビューとフロントエンド - Turbo、Stimulus、CSS、パーシャル
- アーキテクチャ - ルーティング、マルチテナンシー、認証、ジョブ、キャッシング
- テスト - Minitest、フィクスチャ、結合テスト
- Gemと依存関係 - 使用すべきものと避けるべきもの
- コードレビュー - DHHスタイルに照らしたコードレビュー
- 一般的なガイダンス - 哲学と慣習
番号を指定するか、タスクを説明してください。 </intake>
<routing> | レスポンス | 参照資料 | |----------|-------------------| | 1, "controller" | controllers.md | | 2, "model" | models.md | | 3, "view", "frontend", "turbo", "stimulus", "css" | frontend.md | | 4, "architecture", "routing", "auth", "job", "cache" | architecture.md | | 5, "test", "testing", "minitest", "fixture" | testing.md | | 6, "gem", "dependency", "library" | gems.md | | 7, "review" | すべての参照資料を読み、コードをレビュー | | 8, general task | コンテキストに基づいて関連する参照資料を読む |
関連する参照資料を読んだ後、ユーザーのコードにパターンを適用してください。 </routing>
<quick_reference>
命名規則
動詞: card.close, card.gild, board.publish(set_style メソッドではない)
述語: card.closed?, card.golden?(関連レコードの有無から派生)
Concern: 機能を表す形容詞(Closeable, Publishable, Watchable)
コントローラー: リソースに一致する名詞(Cards::ClosuresController)
スコープ:
chronologically,reverse_chronologically,alphabetically,latestpreloaded(標準的なEager Loading名)indexed_by,sorted_by(パラメータ化されたもの)active,unassigned(ビジネス用語であり、SQL的なものではない)
RESTマッピング
カスタムアクションの代わりに、新しいリソースを作成します。
POST /cards/:id/close → POST /cards/:id/closure
DELETE /cards/:id/close → DELETE /cards/:id/closure
POST /cards/:id/archive → POST /cards/:id/archival
Ruby構文の好み
# 角括弧内にスペースを含むシンボル配列
before_action :set_message, only: %i[ show edit update destroy ]
# プライベートメソッドのインデント
private
def set_message
@message = Message.find(params[:id])
end
# 条件分岐のための式のないcase
case
when params[:before].present?
messages.page_before(params[:before])
else
messages.last_page
end
# 失敗を早く知らせるためのバンメソッド
@message = Message.create!(params)
# シンプルな条件分岐のための三項演算子
@room.direct? ? @room.users : @message.mentionees
主要なパターン
レコードとしての状態:
Card.joins(:closure) # closed cards
Card.where.missing(:closure) # open cards
現在の属性:
belongs_to :creator, default: -> { Current.user }
モデルでの認可:
class User < ApplicationRecord
def can_administer?(message)
message.creator == self || admin?
end
end
</quick_reference>
<reference_index>
ドメイン知識
references/ 内のすべての詳細なパターン:
| ファイル | トピック |
|---|---|
| controllers.md | RESTマッピング、Concern、Turboレスポンス、APIパターン、HTTPキャッシング |
| models.md | Concern、状態レコード、コールバック、スコープ、PORO、認可、ブロードキャスティング |
| frontend.md | Turbo Streams、Stimulusコントローラー、CSSレイヤー、OKLCHカラー、パーシャル |
| architecture.md | ルーティング、認証、ジョブ、Current属性、キャッシング、データベースパターン |
| testing.md | Minitest、フィクスチャ、ユニット/結合/システムテスト、テストパターン |
| gems.md | 使用するものと避けるもの、決定フレームワーク、Gemfileの例 |
</reference_index>
<success_criteria> コードがDHHスタイルに従っているのは、次の場合です。
- コントローラーがリソースに対するCRUD動詞にマッピングされている
- モデルが水平的な振る舞いのためにConcernを使用している
- 状態が真偽値ではなくレコードで追跡されている
- 不要なサービスオブジェクトや抽象化がない
- 外部サービスよりもデータベースをバックエンドとするソリューションが好まれる
- テストがフィクスチャ付きのMinitestを使用している
- インタラクティブ性のためにTurbo/Stimulusを使用している(重いJSフレームワークではない)
- 最新機能(レイヤー、OKLCH、ネスト)を備えたネイティブCSS
- 認可ロジックがUserモデルに存在する
- ジョブがモデルメソッドを呼び出す浅いラッパーである </success_criteria>
<credits> Marc KöによるThe Unofficial 37signals/DHH Rails Style Guideに基づいています。 </credits>
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
<objective> Apply 37signals/DHH Rails conventions to Ruby and Rails code. This skill provides comprehensive domain expertise extracted from analyzing production 37signals codebases (Fizzy/Campfire) and DHH's code review patterns. </objective>
<essential_principles>
Core Philosophy
"The best code is the code you don't write. The second best is the code that's obviously correct."
Vanilla Rails is plenty:
- Rich domain models over service objects
- CRUD controllers over custom actions
- Concerns for horizontal code sharing
- Records as state instead of boolean columns
- Database-backed everything (no Redis)
- Build solutions before reaching for gems
What they deliberately avoid:
- devise (custom ~150-line auth instead)
- pundit/cancancan (simple role checks in models)
- sidekiq (Solid Queue uses database)
- redis (database for everything)
- view_component (partials work fine)
- GraphQL (REST with Turbo sufficient)
- factory_bot (fixtures are simpler)
- rspec (Minitest ships with Rails)
- Tailwind (native CSS with layers)
Development Philosophy:
- Ship, Validate, Refine - prototype-quality code to production to learn
- Fix root causes, not symptoms
- Write-time operations over read-time computations
- Database constraints over ActiveRecord validations </essential_principles>
<intake> What are you working on?
- Controllers - REST mapping, concerns, Turbo responses, API patterns
- Models - Concerns, state records, callbacks, scopes, POROs
- Views & Frontend - Turbo, Stimulus, CSS, partials
- Architecture - Routing, multi-tenancy, authentication, jobs, caching
- Testing - Minitest, fixtures, integration tests
- Gems & Dependencies - What to use vs avoid
- Code Review - Review code against DHH style
- General Guidance - Philosophy and conventions
Specify a number or describe your task. </intake>
<routing> | Response | Reference to Read | |----------|-------------------| | 1, "controller" | controllers.md | | 2, "model" | models.md | | 3, "view", "frontend", "turbo", "stimulus", "css" | frontend.md | | 4, "architecture", "routing", "auth", "job", "cache" | architecture.md | | 5, "test", "testing", "minitest", "fixture" | testing.md | | 6, "gem", "dependency", "library" | gems.md | | 7, "review" | Read all references, then review code | | 8, general task | Read relevant references based on context |
After reading relevant references, apply patterns to the user's code. </routing>
<quick_reference>
Naming Conventions
Verbs: card.close, card.gild, board.publish (not set_style methods)
Predicates: card.closed?, card.golden? (derived from presence of related record)
Concerns: Adjectives describing capability (Closeable, Publishable, Watchable)
Controllers: Nouns matching resources (Cards::ClosuresController)
Scopes:
chronologically,reverse_chronologically,alphabetically,latestpreloaded(standard eager loading name)indexed_by,sorted_by(parameterized)active,unassigned(business terms, not SQL-ish)
REST Mapping
Instead of custom actions, create new resources:
POST /cards/:id/close → POST /cards/:id/closure
DELETE /cards/:id/close → DELETE /cards/:id/closure
POST /cards/:id/archive → POST /cards/:id/archival
Ruby Syntax Preferences
# Symbol arrays with spaces inside brackets
before_action :set_message, only: %i[ show edit update destroy ]
# Private method indentation
private
def set_message
@message = Message.find(params[:id])
end
# Expression-less case for conditionals
case
when params[:before].present?
messages.page_before(params[:before])
else
messages.last_page
end
# Bang methods for fail-fast
@message = Message.create!(params)
# Ternaries for simple conditionals
@room.direct? ? @room.users : @message.mentionees
Key Patterns
State as Records:
Card.joins(:closure) # closed cards
Card.where.missing(:closure) # open cards
Current Attributes:
belongs_to :creator, default: -> { Current.user }
Authorization on Models:
class User < ApplicationRecord
def can_administer?(message)
message.creator == self || admin?
end
end
</quick_reference>
<reference_index>
Domain Knowledge
All detailed patterns in references/:
| File | Topics |
|---|---|
| controllers.md | REST mapping, concerns, Turbo responses, API patterns, HTTP caching |
| models.md | Concerns, state records, callbacks, scopes, POROs, authorization, broadcasting |
| frontend.md | Turbo Streams, Stimulus controllers, CSS layers, OKLCH colors, partials |
| architecture.md | Routing, authentication, jobs, Current attributes, caching, database patterns |
| testing.md | Minitest, fixtures, unit/integration/system tests, testing patterns |
| gems.md | What they use vs avoid, decision framework, Gemfile examples |
</reference_index>
<success_criteria> Code follows DHH style when:
- Controllers map to CRUD verbs on resources
- Models use concerns for horizontal behavior
- State is tracked via records, not booleans
- No unnecessary service objects or abstractions
- Database-backed solutions preferred over external services
- Tests use Minitest with fixtures
- Turbo/Stimulus for interactivity (no heavy JS frameworks)
- Native CSS with modern features (layers, OKLCH, nesting)
- Authorization logic lives on User model
- Jobs are shallow wrappers calling model methods </success_criteria>
<credits> Based on The Unofficial 37signals/DHH Rails Style Guide by Marc Köhlbrugge, generated through deep analysis of 265 pull requests from the Fizzy codebase.
Important Disclaimers:
- LLM-generated guide - may contain inaccuracies
- Code examples from Fizzy are licensed under the O'Saasy License
- Not affiliated with or endorsed by 37signals </credits>