Claude CodeでRailsアプリを開発する手順とscaffoldの使い分け
Claude CodeでRailsアプリを開発する手順を解説します。モデルやコントローラーの実装、rails generate scaffoldとの使い分けが分かります。
Claude CodeでRailsアプリを開発するとは
Claude CodeでRailsアプリを開発するとは、rails newやbin/rails generateといったRailsコマンドをClaude Codeのターミナルセッション内で実行する進め方です。モデル・ビュー・コントローラーの実装をエージェントに任せられます。Claude Codeはプロジェクトのファイルを必要に応じて自動で読み込むため、手作業でコンテキストを渡す必要がありません。
Railsアプリ自体はMVC(Model・View・Controller)で構成されます。モデルはデータベースのテーブルを、ビューはHTML・JSONなどのレスポンス生成を、コントローラーはリクエストごとの処理をそれぞれ担当します。Claude Codeはこの3層をまたいだ変更を一度の指示でまとめて実装できる点が、単体のコード補完ツールとの違いです。
プロジェクトルートにCLAUDE.mdを置いておくと、Claude Codeはセッション開始時にこのファイルを読み込みます。モデル名は単数形、テーブル名は複数形といったRailsの命名規約や、使用するテストフレームワークをここに書いておけば、生成のたびに同じ指示を繰り返さずに済みます。
開発を始める前の準備
開発を始める前に、Ruby・Rails・Claude Codeの3つを用意します。RailsのGetting Startedガイドが前提とするバージョンは次のとおりです。
| 項目 | 必要バージョン |
|---|---|
| Ruby | 必要バージョン3.2以降 |
| Rails | 必要バージョン8.1.0以降 |
| コードエディタ | 必要バージョン任意 |
Rails自体がインストール済みかは、次のコマンドで確認できます。
rails --versionClaude Codeはネイティブインストーラーで導入します。macOS・Linux・WSLでは以下のコマンドを実行し、インストール後にclaude --versionでバージョンを確認します。
curl -fsSL https://claude.ai/install.sh | bash
claude --version初回はclaudeコマンドを実行するとブラウザでの認証を求められます。ANTHROPIC_API_KEY環境変数を設定している場合は、ログイン画面の代わりにキーの承認を求められる点が異なります。
アプリの規模が大きく、テーブル設計や画面遷移を先に固めたいときは、いきなり生成コマンドを打つのではなく仕様を先に固める進め方も選べます。cc-sddでClaude Codeの仕様駆動開発を実践するは、この段取りを具体的に扱っています。ローカルにRubyを入れずコンテナで開発したい場合は、Docker/Podman/Kubernetes MCPの選び方が開発環境の選定に役立ちます。
ステップ1: Railsアプリの雛形をClaude Codeに作らせる
rails newはRailsアプリの土台一式を生成するコマンドです。ここでは公式ガイドに倣い、storeという名前のシンプルなECアプリを作ります。
rails new store
cd store生成後はstoreディレクトリの中でclaudeコマンドを実行し、Claude Codeのセッションを開始します。app/にモデル・ビュー・コントローラーが、config/にルーティングとデータベースの設定がまとまっています。以降のステップは、このディレクトリ内でClaude Codeに指示を出す形で進めます。
データベース作成とサーバー起動は次の2つのコマンドで行います。アプリ内のコマンドを実行するときは、システム全体のRailsではなくアプリに同梱されたbin/railsを使うのが基本です。
bin/rails db:create
bin/rails serverhttp://localhost:3000を開くと、Railsの初期ページが表示されます。開発中はファイルの変更が自動で検知され再読み込みされるため、サーバーを都度再起動する必要はありません。
ステップ2: モデルとマイグレーションを生成する
商品を表すProductモデルを追加します。Claude Codeに「name属性を持つProductモデルを追加して」と指示すると、内部的には次のコマンドが実行されます。
bin/rails generate model Product name:stringこのコマンドはdb/migrate/にマイグレーションファイル、app/models/product.rbにモデルクラス、加えてテスト用のファイルを生成します。モデル名は単数形(Product)、対応するデータベースのテーブル名は複数形(products)になる点がRailsの規約です。
生成されたマイグレーションを実際のデータベースに反映するには、次のコマンドを実行します。
bin/rails db:migrateマイグレーションを間違えて実行してしまった場合は、bin/rails db:rollbackで直前の変更を取り消せます。反映後はbin/rails consoleを起動し、Product.column_namesを実行すると、データベースの列情報からClaude Codeが定義した属性を確認できます。
ステップ3: コントローラーとルーティングを実装する
次にコントローラーとルーティングを追加します。config/routes.rbにresources :productsを1行書くだけで、一覧・詳細・作成・更新・削除に対応するRESTfulなルートがまとめて定義されます。
Rails.application.routes.draw do
root "products#index"
resources :products
endルートはすでに定義済みのため、コントローラー生成では--skip-routesフラグを付けてルーティングの重複を避けます。
bin/rails generate controller Products index --skip-routes生成されたProductsControllerのindexアクションにデータベースへの問い合わせを1行加えると、ビューへデータを渡せるようになります。
class ProductsController < ApplicationController
def index
@products = Product.all
end
endビュー側では、コントローラーが設定したインスタンス変数@productsをERB(Embedded Ruby)でループし、商品名を表示します。ここまでの3ステップでMVCの最小構成が動く状態になります。
scaffoldとresource、個別生成はどう使い分けるか
ここまではモデル・コントローラー・ルーティングを1つずつ手作業で生成しました。Railsにはこれを一括で行う生成コマンドも用意されており、用途によって使い分けます。
| コマンド | 生成されるもの | 向いている場面 |
|---|---|---|
generate model + generate controller | 生成されるものモデル・コントローラーを個別に。ビューは書かない | 向いている場面ロジックを自分で組み立てたいとき |
generate resource | 生成されるものモデル・マイグレーション・空のコントローラー・ルーティング・テスト(ビューなし) | 向いている場面APIなどビュー不要なCRUD |
generate scaffold | 生成されるものモデル・コントローラー・ビュー(HTML/JSON)・ルーティング・マイグレーション・テストを一式 | 向いている場面プロトタイプを素早く動かしたいとき |
resourceコマンドはscaffoldより軽量で、生成するコードも少なく済みます。一方scaffoldは、CRUD一式の画面までまとめて必要になる場面で威力を発揮します。
bin/rails generate scaffold post title:string body:textこのコマンド1つで、postsテーブルのマイグレーション、Postモデル、PostsController、一覧・詳細・新規作成・編集用のビュー、JSON形式のビューまで生成されます。生成後はbin/rails db:migrateを忘れずに実行します。
Claude Codeに指示を出すときは「Product用にscaffoldを生成して」と伝えれば一括生成、「モデルとルーティングだけ先に作って、コントローラーは後で実装を相談したい」と伝えれば個別生成、という使い分けがそのまま反映されます。
Claude Codeにbin/railsコマンドの実行権限を渡す
Claude CodeはBashツールでbin/railsコマンドを実行しますが、実行のたびに確認を求められるとテンポが落ちます。Pro・Max・Teamプランのインタラクティブセッションでは、既定でAuto modeが有効になっており、分類器がコマンドの安全性を判断してほとんどのコマンドを確認なしで実行します。
より細かく制御したい場合は、プロジェクト直下の.claude/settings.jsonに許可・拒否ルールを書きます。
{
"permissions": {
"allow": [
"Bash(bin/rails generate *)",
"Bash(bin/rails db:migrate)",
"Bash(bin/rails test)"
],
"deny": [
"Bash(bin/rails db:drop)"
]
}
}ルール中の*はサブコマンドより後ろに置きます。Bash(bin/rails generate *)はgenerate配下のコマンドだけを許可します。Bash(bin/rails *)のように書くと、db:dropを含むすべてのbin/railsコマンドが許可されてしまいます。deny・ask・allowの順で評価され、拒否ルールは同じ呼び出しにマッチする許可ルールより常に優先されます。
CIやリモートの開発機からClaude Codeにbin/rails testを実行させたい場合は、Claude apps gatewayをCIやリモート開発機から使うにはがゲートウェイ経由の接続方法をまとめています。
よくあるつまずき
生成コマンドのタイプミスに気づかず実行してしまう
ProductのつもりでArtcleのように打ち間違えると、誤った名前のファイル一式が生成されます。bin/rails destroyはgenerateの逆で、実行済みの生成コマンドが作ったファイルを自動で判別して削除します。
bin/rails destroy model Artcle title:string body:textマイグレーションを作っただけで反映を忘れる
generate modelはマイグレーションファイルを作るだけで、データベースへの反映は別操作です。bin/rails db:migrateを実行し忘れると、コンソールやビューで「テーブルが存在しない」というエラーになります。
単数形と複数形を取り違える
モデルクラスは単数形(Product)、データベースのテーブル名やルーティングのresourcesは複数形(products)で書きます。逆にすると生成コマンドが想定と異なるファイル名・テーブル名を作ってしまいます。
--skip-routesを忘れてルーティングが重複する
resources :productsですでにルートを定義済みの状態でgenerate controllerを素のまま実行すると、ルーティングの生成もあわせて走ります。結果としてconfig/routes.rbに重複した記述が残ります。
まとめ
Claude CodeでRailsアプリを開発する流れは、rails newでアプリを作り、generate modelとgenerate controllerでMVCの各層を組み立てる手順です。最後にdb:migrateでデータベースに反映する、という繰り返しになります。プロトタイプを素早く形にしたいときはscaffold、実装を自分でコントロールしたいときは個別生成、という使い分けが判断の軸になります。
権限設定を.claude/settings.jsonに書いておけば、bin/rails generateやdb:migrateのたびに確認を求められることもありません。ローカルでの実装が固まった後、Kamal以外のデプロイ先としてHerokuを使う場合はHeroku MCPサーバーでClaude Codeからアプリをデプロイ・スケーリングするが具体的な手順を扱っています。