rails generate(略記 rails g)は、モデル・コントローラ・マイグレーションなどの雛形を命名規則どおりに作るコマンドです。この記事では、各ジェネレータが何を作るかをRails 8.1.4(2026年9月24日リリース)を実際に実行したログで一覧にし、カラムの書き方、rails destroyで取り消すときに残るもの、生成ファイルを減らす設定、独自ジェネレータの作り方までを扱います。検証はRuby 4.0.6・rails newの既定構成(SQLite・Minitest)で行いました。開発環境がまだの場合はruby on rails を vscode で開発する環境構築【2026年版】Ruby LSP・デバッグ・Dev Containerから始めてください。
まとめ:rails generateの要点(Rails 8.1.4)
rails gはrails generate、rails dはrails destroyの別名です。引数なしのbin/rails generateで一覧が出ます(Railsグループは20種類)。- modelはモデル・マイグレーション・テスト・フィクスチャ、controllerはコントローラ・アクションごとのビュー・ルート・ヘルパー・テストを作ります。scaffoldはその両方に加えてCRUDのビューとJSON用jbuilderまで作ります。
- Rails 8.1からscaffoldはシステムテストを作りません。必要なら
--system-tests=trueを付けます。 - カラムは
名前:型{長さ}:indexの形で書き、!(Rails 8.0以降)でnull: falseになります。decimal{10,2}はシェルが展開してしまうので引用符で囲みます。 rails destroyは生成ファイルの削除や対応するルートの除去を行いますが、適用済みのマイグレーションは戻しません。db:migrate済みならテーブルが残るので、先にdb:rollbackします。controllerはアクション名まで渡さないとルートが残ります。- 不要な生成物は
config.generatorsか--no-helperなどのオプションで止め、独自の雛形はrails g generatorかlib/templatesで作ります。
rails generateの基本と一覧の出し方
rails g・rails destroy・–pretendの関係
rails gとrails generateに動作の違いはありません。取り消しは同じ引数をrails destroy(rails d)に渡します。何が作られるかだけ見たいときは-p(--pretend)を付けると、ログは通常どおり出ますがファイルは作られません。実際にbin/rails g model Draft --pretend title:stringを実行したあとdb/migrateを確認しても、draftsのマイグレーションはありませんでした。
bin/rails g model Article title:string -p # 生成予定だけ表示
bin/rails g model Article title:string # 生成
bin/rails d model Article # 取り消し
bin/rails g model --help # modelジェネレータのオプション一覧
アプリのディレクトリ内ではbin/railsを使うと、そのアプリのGemfileに書かれた版のRailsで動きます。共通オプションは-pのほか、既存ファイルを上書きする-f(--force)、既存ファイルを飛ばす-s(--skip)、ログを出さない-q(--quiet)です。
Rails 8.1.4で使えるジェネレータ(20種類)
rails new直後のアプリでbin/rails generateを引数なしで実行すると、「Rails:」の下に次の20種類が並びました。
application_record authentication benchmark channel controller
generator helper integration_test jbuilder job mailbox mailer
migration model resource scaffold scaffold_controller script
system_test task
その下にはsolid_queue:installやstimulusなど、Gemfileに入っているgemが登録したジェネレータが別のグループで続きます。viewという単独のジェネレータは無く、bin/rails g view Fooは「Could not find generator ‘view’.」で終了コード1になります。ビューはcontrollerかscaffoldが作ります。
Rails 8.0で増えたのがauthenticationとscriptです(railties 8.0のCHANGELOG)。authenticationはセッション・パスワードリセットのコントローラとモデル、email_address:string!:uniqを持つusersテーブルのマイグレーションを作り、Gemfileのbcryptのコメントを外してbundle installまで実行します。既にUserモデルがあるアプリではapp/models/user.rbの上書き確認が出るので、既存アプリへ入れるときは先にブランチを切ってください。bin/rails g script cleanupはscript/cleanup.rbを1つ作るだけで、データ移行などの使い捨て処理の置き場になります。
コマンド別の生成ファイル早見表
Rails 8.1.4の既定構成で、各ジェネレータを実行したときに作られたものです(○=作る、-=作らない)。
| コマンド | モデル | マイグレーション | コントローラ | ビュー | ルート | ヘルパー | テスト | jbuilder |
|---|---|---|---|---|---|---|---|---|
| model | ○ | ○ | - | - | - | - | ○(+fixture) | - |
| controller | - | - | ○ | ○(アクション分) | ○(get) | ○ | ○ | - |
| resource | ○ | ○ | ○(空) | 空フォルダ | ○(resources) | ○ | ○ | - |
| scaffold | ○ | ○ | ○(7アクション) | ○(6ファイル) | ○(resources) | ○ | ○ | ○ |
| scaffold_controller | - | - | ○(7アクション) | ○(6ファイル) | ○(resources) | ○ | ○ | ○ |
| migration | - | ○ | - | - | - | - | - | - |
2023年ごろの解説記事では、scaffoldがtest/system/posts_test.rbまで作るログが載っています。Rails 8.1.0で「scaffoldは既定でシステムテストを作らない」に変わったため(railties 8.1.4のCHANGELOGの8.1.0の項)、今の版で同じログにはなりません。CSSなどのアセットも今のscaffoldは作りません。
モデルを作る:rails generate model
モデル名は単数形で書きます。bin/rails g model Article title:string body:text user:references published:booleanを実行すると、app/models/article.rb、db/migrate/日時_create_articles.rb、test/models/article_test.rb、test/fixtures/articles.ymlの4ファイルができ、マイグレーションの中身は次のとおりでした。
class CreateArticles < ActiveRecord::Migration[8.1]
def change
create_table :articles do |t|
t.string :title
t.text :body
t.references :user, null: false, foreign_key: true
t.boolean :published
t.timestamps
end
end
end
referencesを書いたので、モデル側にもbelongs_to :userが入ります。生成後はbin/rails db:migrateで適用し、関連の逆側(has_many)やバリデーションを書き足します。関連の種類と書き分けはRailsのAssociationとは?6種類の関連付けと使い分け・実装手順、モデルとテーブルの対応そのものはActive Record(アクティブレコード)とは?Railsを支える設計パターンと基本を実例で解説で扱っています。
カラム型と修飾子({}・:index・:uniq・!)
型はstring・text・integer・float・decimal・boolean・date・datetime・time・binaryなどを使えます。型を省くとstringになります。修飾子を付けたときの出力は次のとおりです。
| 書き方 | マイグレーションの出力 |
|---|---|
name:string{50} |
t.string :name, limit: 50 |
'price:decimal{10,2}' |
t.decimal :price, precision: 10, scale: 2 |
email:string:uniq |
add_index :users, :email, unique: true |
published_at:datetime:index |
add_index(一意でない) |
'title:string!' |
t.string :title, null: false |
!修飾子はRails 8.0で入りました。Rails 8.1.4では、生成コマンドを文字列に戻すときにも!を出すよう修正されています。
references・polymorphic・digest・tokenの生成結果
user:references(user:belongs_toも同じ):t.references :user, null: false, foreign_key: trueとbelongs_to :user。commentable:references{polymorphic}:t.references :commentable, polymorphic: true, null: false。参照先が1つに決まらないので外部キー制約は付きません。password:digest:password_digest列とhas_secure_password。api_token:token:一意インデックス付きのapi_token列とhas_secure_token :api_token。
digestには落とし穴があります。rails new直後のGemfileはbcryptが# gem "bcrypt", "~> 3.1.7"とコメントアウトされたままで、この状態でbin/rails g model Account password:digestを実行すると、フィクスチャの生成でuninitialized constant ... BCrypt (NameError)が出て終了コード1で止まりました。その時点でマイグレーション・モデル・テストは作られたままです。bcryptのコメントを外してbundle installしてからbin/rails d model Accountで消し、もう一度生成します。
decimal{10,2}の引用符とブレース展開
bashでもzshでも、引用符なしのprice:decimal{10,2}はブレース展開でprice:decimal10 price:decimal2の2語に変わります。実行すると「Could not generate field ‘price’ with unknown type ‘decimal10’.」と出て何も作られないのに終了コードは0でした。スクリプトやCIで流すと失敗に気づけません。カンマを含む{}は'price:decimal{10,2}'のように引用符で囲みます。{50}のようにカンマが無ければ展開されません。!を含む引数も、bashの履歴展開を避けるため引用符で囲んでおくと安全です。
コントローラを作る:rails generate controller
コントローラ名は複数形で、続けてカラムではなくアクション名を並べます。bin/rails g controller Articles index showのログは次のとおりでした。
create app/controllers/articles_controller.rb
route get "articles/index"
get "articles/show"
invoke erb
create app/views/articles
create app/views/articles/index.html.erb
create app/views/articles/show.html.erb
invoke test_unit
create test/controllers/articles_controller_test.rb
invoke helper
create app/helpers/articles_helper.rb
追記されるルートはget "articles/index"の形で、resources :articlesにはなりません。RESTの7アクションの実装まで生成するならscaffoldを使います。resourceはRESTのルートを追加しますが、既定ではコントローラのアクションを実装しません。Admin::Usersのように名前空間を付けると、app/controllers/admin/users_controller.rbができ、ルートはnamespace :admin doのブロックの中に入りました。ルート追記が不要なら--skip-routes、ヘルパーが不要なら--no-helper、テストが不要なら--skip-test-frameworkを付けます。アクション名を書かなければ、既定構成では空のコントローラ、ビューのフォルダ、ヘルパー、コントローラのテストが生成されます。アクション別のビューとルートは生成されません。
scaffoldで一式を作る:rails generate scaffold
bin/rails g scaffold Post title:string body:textは、モデル・マイグレーション・resources :posts・7アクションのコントローラに加え、ビューをindex・edit・show・new・_form・_postの6ファイル、JSON用にindex.json.jbuilder・show.json.jbuilder・_post.json.jbuilderを作りました。生成されたコントローラは、保存に失敗したときstatus: :unprocessable_contentで返し、更新・削除後のリダイレクトにはstatus: :see_otherを付けます。Turboの画面遷移がこの値を前提にしているので、書き換えるときも残します。
scaffoldのシステムテスト生成オプション
前述のとおりRails 8.1のscaffoldはシステムテストを作りません。--system-tests=trueを付けるとtest/application_system_test_case.rbとtest/system/posts_test.rbが追加されます。あとから足すならbin/rails g system_test postsです。RSpecでリクエストを検証したい場合はrequest specとは?Rails 8・RSpec 8でのリクエストスペックの書き方を参照してください。
scaffoldを使う場面・使わない場面
scaffoldが向くのは、学習用・試作・社内の単純なマスタ管理のように、標準のCRUD画面をほぼそのまま使える場面です。業務ルールが絡む画面には使わないほうがよいです。7アクション・6ビュー・jbuilderのうち実際に使うのが一部なら、残りは誰も読まないコードとして残り続けます。その場合はmodelとcontrollerを個別に作り、必要なアクションだけ書きます。通常のアプリで--apiを付けたドライランでは、erbのビューは生成対象に含まれず、ヘルパーとjbuilderが生成予定として表示されました。画面を持たないAPIサーバーは、最初からrails new --apiで作るほうが不要物が出ません(Rails APIとは?作成手順・JWT認証・React連携・Docker環境を実装解説【Rails 8.1】)。雛形で済まない業務システムの設計・開発を外部に任せる場合は、フルスクラッチ開発の支援内容も参考になります。
マイグレーションを作る:rails generate migration
マイグレーションは名前の付け方で中身が組み立てられます。実行して出力された処理は次のとおりです。
| コマンドの引数 | 生成された処理 |
|---|---|
AddPublishedAtToArticles published_at:datetime:index |
add_column+add_index |
RemoveBodyFromArticles body:text |
remove_column :articles, :body, :text |
AddUserRefToPosts user:references |
add_reference :posts, :user, null: false, foreign_key: true |
CreateJoinTableArticlesTags articles tags |
create_join_table :articles, :tags |
Remove系では型まで書いておくと、remove_columnに型が入り、db:rollbackで列を戻せます。CreateJoinTableは2つのインデックスがコメントアウトされた状態で生成されるので、検索に使う向きのものを外して有効にします。[8.1]は生成時のRailsのマイグレーションAPIの版です。既存のadd_columnでは済まない、本番の大きなテーブル変更や宣言的なスキーマ管理についてはRidgepoleとは?Schemafileでスキーマを管理する使い方と落とし穴で比較しています。
rails destroyで生成を取り消すときの落とし穴
rails destroyは生成したファイルを消すコマンドで、データベースやルートを元に戻す処理は一部しか持っていません。検証で次の2点が分かりました。
マイグレーション適用後のrollbackとdestroyの実行順
Bookモデルを生成してdb:migrateしたあとにbin/rails d model Bookを実行すると、マイグレーションファイルは消えますが、booksテーブルは残り、db/schema.rbにも定義が残りました。db:migrate:statusには次の行が出ます。
up 20261027050723 ********** NO FILE **********
ファイルが無いのでこの状態からはdb:rollbackできません。正しい順番は、bin/rails db:rollback(複数前ならdb:migrate:down VERSION=日時)でテーブルを戻してからdestroyです。順番を間違えたら、同じ名前でもう一度generateしてファイルを作り直すのではなく、gitで消えたマイグレーションを戻してからrollbackします(作り直すと日時が変わり別のマイグレーションになります)。
controller削除時のアクション指定とルートの残存
bin/rails g controller Articles indexのあとにbin/rails d controller Articlesとアクション名を省いて実行すると、ファイルは消えてもconfig/routes.rbのget "articles/index"は残りました。bin/rails d controller Articles indexと生成時と同じアクション名を渡すと、ログにrouteの行が出てルートも消えます。controllerジェネレータのソースで、アクションが空のときはルートの処理を丸ごと飛ばす(return if actions.empty?)ためです。scaffoldとresourceのresources :postsは名前だけのdestroyで消えました。
生成ファイルを減らす設定:config.generators
毎回オプションを付ける代わりに、config/application.rbで既定を変えられます。次の設定でscaffoldを実行すると、ヘルパー・jbuilder・テストが作られず、マイグレーションはcreate_table :notes, id: :uuidになりました。
# config/application.rb
config.generators do |g|
g.helper false
g.jbuilder false
g.test_framework nil
g.orm :active_record, primary_key_type: :uuid
end
primary_key_type: :uuidはPostgreSQLのようにUUID型を持つデータベース向けです。RSpecへの切り替えはこの設定に書かなくても済みます(下のよくある質問を参照)。1回だけ止めたい場合は--no-helper・--no-jbuilder・--skip-test-frameworkのようにコマンド側で指定します。
カスタムジェネレータとテンプレートの上書き
チームで同じ形のクラスを繰り返し作るなら、ジェネレータにしておくと命名と置き場所がそろいます(Rails Guides: Creating and Customizing Rails Generators & Templates)。
rails generate generatorによる雛形の生成
bin/rails g generator serviceでlib/generators/service/の下にservice_generator.rb・USAGE・templates/ができます。既定のMinitest構成では、これらに加えてtest/lib/generators/service_generator_test.rbも生成されます。本体はRails::Generators::NamedBaseを継承し、source_rootだけが書かれた状態です。
NamedBaseとclass_optionによるサービス生成の実装
サービスクラスを作るジェネレータを次のように書きました。publicメソッドは定義順に実行され、class_nameやfile_nameは引数の名前から作られます。
# lib/generators/service/service_generator.rb
class ServiceGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
class_option :call, type: :boolean, default: true, desc: "Define .call"
def create_service_file
template "service.rb.tt", File.join("app/services", class_path, "#{file_name}_service.rb")
end
end
# lib/generators/service/templates/service.rb.tt
class <%= class_name %>Service
<% if options[:call] -%>
def self.call(...) = new(...).call
<% end -%>
def call
end
end
bin/rails g service Billing::Chargeでapp/services/billing/charge_service.rbにclass Billing::ChargeServiceができ、--no-callを付けるとself.callの行が消えました。class_optionに書いたdescはbin/rails g service --helpに表示され、bin/rails d service Refundで取り消しもできます。肥大化したモデルからサービスクラスへ処理を移すときの判断はRailsのFat Model対策|1500行model.rbを分割する4手法と判断基準にまとめています。
lib/templatesによる標準テンプレートの差し替え
新しいジェネレータを作らなくても、標準ジェネレータのテンプレートはアプリのlib/templatesに同じパスで置くと差し替えられます。lib/templates/active_record/model/model.rb.ttにコメント行を足したテンプレートを置いてbin/rails g model Tag name:stringを実行すると、app/models/tag.rbはそのテンプレートの内容で作られました。scaffoldのビューならlib/templates/erb/scaffold/index.html.erb.ttです。元のテンプレートは、モデル用がactiverecord、ERBのscaffoldビュー用がrailtiesの各gemにあるlib/rails/generators以下に置かれているので、コピーしてから書き換えると差分が小さく済みます。
よくある質問
rails generate viewというコマンドはありますか?
ありません。Rails 8.1.4でbin/rails g view Fooを実行すると「Could not find generator ‘view’.」で止まります。ビューだけ欲しいときはbin/rails g controller Foos indexのようにアクション名を付けてcontrollerを作るか、app/viewsに直接ファイルを置きます。
rails g と rails generate に違いはありますか?
違いはありません。rails gはrails generateの別名で、rails dもrails destroyの別名です。
rails g model で references を指定すると何が作られますか?
user:referencesなら、マイグレーションにt.references :user, null: false, foreign_key: true(インデックス付き)、モデルにbelongs_to :userが入ります。参照先のusers参照される側のusersテーブルを先に作るのが基本です。ただし、SQLiteでは参照先がなくても外部キー付きテーブルの作成自体は成功し、後続のデータ操作などでエラーになる場合があります。
生成の途中でエラーになり、ファイルが一部だけ作られたときは?
エラーの前に作られたファイルは残ります。原因(たとえばpassword:digestならbcryptのgem)を直したら、同じ引数でrails destroyを実行して消し、生成し直します。db:migrateまで進めていない段階なら、テーブルの後始末は要りません。
RSpecでテストファイルを生成するには?
Gemfileのdevelopment・testグループにrspec-railsを入れるだけで切り替わります。rspec-rails 8.0.4を入れたアプリでは、config.generatorsを書かなくてもbin/rails g model Widget name:stringのログがinvoke rspecになり、test/の代わりにspec/models/widget_spec.rbがドライランで生成予定として表示されました(フィクスチャは生成対象に含まれません)。spec_helper.rbなどの設定ファイルはbin/rails g rspec:installで別に作ります。