Rails 8 にバージョンを上げたら、今まで動いていた enum が急に ArgumentError: wrong number of arguments (given 0, expected 1..2) でエラーになった——そんな場面に出くわしていませんか?
これは Rails 8 で enum の「旧記法」が完全に使えなくなったのが原因です。バグではなく仕様変更なので、書き方を直すしかありません。とはいえ直し方はとてもシンプルです。
この記事では、まず一番知りたい「どう直すか」を先に示したうえで、なぜ変わったのかの経緯、prefix / suffix オプションの落とし穴、既存プロジェクトを一括で移行する手順まで、実務目線でまとめます。

:status, の形で第1引数に出せば、値の中身は変えずにエラーが消えます。まず結論:属性名を第1引数に出すだけ
直し方は一行です。属性名をキーワード引数ではなく、第1引数のシンボルとして外に出す。これだけで Rails 8 のエラーは消えます。
# ❌ 旧記法(Rails 8 でエラー)
enum status: { draft: 0, published: 1, archived: 2 }
# ✅ 新記法(Rails 7〜8 で有効)
enum :status, { draft: 0, published: 1, archived: 2 }違いは status:(コロンが後ろ)を :status,(コロンが前・カンマ区切り)に変えただけです。値の中身({ draft: 0, ... })は一切いじりません。
エラーメッセージが given 0, expected 1..2(引数が0個だが1〜2個が必要)となっているのは、旧記法だと Rails 8 が「第1引数(属性名)が渡されていない」と解釈するためです。属性名を第1引数に出せば given 1 となり、正しく通ります。
なぜ変わったのか:Rails 7.2で非推奨 → Rails 8で使用禁止
この新記法自体は、実は Rails 7 の頃から使えるようになっていました。段階を追うとこうです。
- Rails 7:新記法
enum :status, {...}が追加される(旧記法もまだ使える) - Rails 7.2:旧記法
enum status: {...}が 非推奨(deprecation 警告)になる - Rails 8.0:旧記法が完全に削除され、使うと
ArgumentErrorになる
つまり Rails 7.2 の時点でログに警告が出ていたはずで、それを放置したまま 8 に上げるとエラーとして噴き出す、という流れです。まだ 7.x を使っている人も、警告が出ているなら今のうちに新記法へ直しておくと、8 へのアップグレードがそのぶん楽になります。
なぜわざわざ変えたのかというと、後述する prefix などのオプションを、enum の値と混ざらない形で渡せるようにするためです。「属性名は第1引数」「値はハッシュ」「オプションは末尾」と役割がはっきり分かれ、書き方のブレがなくなります。
enumの基本をおさらい:何が”生える”のか
ここで、そもそも enum が何をしてくれるのかを軽くおさらいしておきます(新記法で書きます)。整数カラム status を持つ Post モデルを例にします。
class Post < ApplicationRecord
enum :status, { draft: 0, published: 1, archived: 2 }
endこれだけで、次のようなメソッドが自動的に生えます。
post = Post.new
post.draft! # ステータスを draft に更新
post.published? # published かどうかを判定(true / false)
post.status # => "draft" のように文字列で取得
Post.published # published のレコードだけを引くスコープ
Post.statuses # => {"draft"=>0, "published"=>1, "archived"=>2}ポイントは、コード上は draft / published という名前で扱えるのに、DBには 0 / 1 という整数で保存されることです。人間に読みやすい名前と、DBに効率よく入る整数を両立できるのが enum の便利なところです。

prefix / suffix / default オプションの新記法
オプションを付ける場合は、ハッシュの後ろにキーワード引数として渡します。ここが旧記法との一番の違いであり、ハマりどころでもあります。
# prefix を付けると status_published? のように接頭辞が付く
enum :status, { draft: 0, published: 1 }, prefix: true
# => post.status_published? / post.status_draft!
# suffix なら published_status? のように接尾辞になる
enum :status, { draft: 0, published: 1 }, suffix: true
# default で新規レコードの初期値を決められる
enum :status, { draft: 0, published: 1 }, default: :draft旧記法では _prefix / _suffix / _default のようにアンダースコア付きで書いていました。新記法では、このアンダースコアが取れます(prefix / suffix / default)。
要注意:新記法で「_prefix」を書くと黙って無視される
ここが一番の落とし穴です。新記法(属性名を第1引数に出す形)で、うっかり旧オプション名 _prefix: true のまま書くと、エラーにならずに黙って無視されます。
# ❌ 新記法なのに _prefix(アンダースコア付き)
# → エラーは出ないが prefix が効かず、post.status_draft! が生えない
enum :status, { draft: 0, published: 1 }, _prefix: true
# ✅ アンダースコアなし
enum :status, { draft: 0, published: 1 }, prefix: trueエラーで止まってくれれば気づけますが、無視されるだけなので厄介です。「新記法に直したのに status_published? が NoMethodError になる」ときは、まずオプションのアンダースコアが残っていないかを疑ってください。
つまずきやすいケース別の書き方
1つのモデルに複数のenumを持たせる
旧記法では複数の属性を1回の enum にまとめて書けましたが、新記法では属性ごとに1行ずつ書きます。こちらのほうが読みやすく、オプションも属性単位で付けられます。
class Order < ApplicationRecord
enum :status, { pending: 0, paid: 1, shipped: 2 }, default: :pending
enum :payment_method, { card: 0, bank: 1, cod: 2 }, prefix: true
end文字列カラムをキーにする
DBのカラムが整数ではなく文字列(varchar)の場合は、値のほうを文字列にします。マイグレーションのカラム型と揃えるのを忘れずに。
enum :status, { draft: "draft", published: "published" }整数キーはDBサイズが小さく速い一方、直接クエリを叩いたときに 0 / 1 が何を指すか分かりません。文字列キーはその逆で、DBを直接見ても意味が読み取れます。運用でSQLを直に叩く機会が多いなら文字列、パフォーマンスと素直さを優先するなら整数、という使い分けが目安です。
既存プロジェクトの旧記法を一括で洗い出す
アップグレード時は、まず旧記法がどこに残っているかを機械的に洗い出すのが確実です。旧記法は enum の直後に「属性名(英字)」が来る、新記法は enum :(コロン)が来る、という違いを使って grep します。
# 旧記法(enum status: ...)だけを拾う
# enum の後ろが「:」ではなく英字で始まる行 = 直すべき箇所
grep -rnE "^\s*enum [a-z]" app/modelsヒットした行を新記法(属性名を :xxx, の形で第1引数に出す)へ直していきます。件数が多いときは、この一覧をそのまま修正のチェックリストにすると漏れがありません。
継続的に防ぎたいなら rubocop-rails の導入も有効です。Rails/EnumSyntax という専用のルール(cop)があり、旧記法を検知してくれるうえ、autocorrect で新記法へ自動修正もできます。CI に組み込んでおけば、うっかり旧記法が混ざるのを防げます。バージョンアップで踏むハマりの調べ方そのものについては、エンジニアの仕事は「知っていること」より「調べられること」もあわせてどうぞ。
まとめ:チェックリスト
Rails 8 の enum 対応で押さえるべき点を最後にまとめます。
wrong number of arguments (given 0, expected 1..2)が出たら enum の記法を疑う- 直し方は「属性名を第1引数のシンボルに出す」だけ:
enum status: {...}→enum :status, {...} - オプションはアンダースコアなし(
prefix/suffix/default)。新記法で_prefixと書くと黙って無視される - 複数 enum は属性ごとに1行ずつ書く
- 既存コードは
grep -rnE "^\s*enum [a-z]" app/modelsで洗い出し、rubocop-railsで再発防止
enum の書き方が変わったのは一見面倒ですが、直し方はワンパターンです。同じ「バージョンアップで踏むハマり」系では、Rails 8の認証ジェネレータとDeviseはどっちを使う?やRails8のsolid_queueなどを使ったdatabase.ymlの書き方もRailsアップグレードのつまずきをまとめているのでRails 8対応の参考にしてください。
スポンサーリンク
