enumとは
Rails で状態管理をするときによく使うのが enum。
「下書き・公開待ち・公開済み」みたいなステータスをきれいに扱える便利機能です。
Rails 8 からは 新しい書き方に統一されたので、その点も含めて整理します。
1. 基本の書き方
モデルファイルに記述
Rails 7.1 以降(推奨・Rails 8で必須)
models/.rb
class Article < ApplicationRecord
enum :state, { draft: 0, publish_wait: 1, published: 2 }
end
Rails 7.0 以前(非推奨・Rails 8で削除)
models/.rb
class Article < ApplicationRecord
enum state: { draft: 0, publish_wait: 1, published: 2 }
end
2.使い方
値の代入
rb
article = Article.new
article.state = :draft
article.save!
• DB の state カラムは integer 型(0, 1, 2…で保存される)
• article.state = :draft と書くと Rails が 0 をセットしてくれる
• コードはシンボルでわかりやすく、DBは数字で効率的 といういいとこ取り
オブジェクトの状態を判定する場合
「キー名 + ?」 で生成されるメソッドを使用することで、特定のレコードの状態を判定できます。
.rb
article = Article.create!(title: "Title", state: "published")
article.draft? # state が "draft" かどうかを判定
=> false
article.publish_wait? # state が "publish_wait" かどうかを判定
=> false
article.published? # state が "published" かどうかを判定
=> true
• enum を定義すると draft? / publish_wait? / published? みたいな 判定メソッドが自動で生える
• これのおかげで article.state == "draft" みたいに文字列比較しなくていい
• 読みやすいしタイプミスしにくい
状態の切り替えメソッド
rb
article.published! # => true/false
• これも enum が自動生成してくれる
• 内部では update!(state: :published) が呼ばれるイメージ
• 保存までしてくれるので、article.state = :published; article.save! と2行書く必要がない
article.published(感嘆符なし)の場合はオブジェクトの属性を更新のみで save はされません。
3. スコープの自動生成
enum を定義すると、自動的にスコープも追加されます。
.rb
Article.draft # status が "draft" のレコードを取得
Article.publish_wait # status が "publish_wait" のレコードを取得
Article.published # state が "published" のレコードを取得
4. オプションいろいろ
状態名がかぶりそうなときに便利です。
rb
class User < ApplicationRecord
enum :role, { admin: 0, member: 1 }, prefix: true
end
user = User.new(role: :admin)
user.role_admin? # => true
user.role_member? # => false
• メソッド名が role_admin? になる
• 例えば「role」以外に「state」とか別の enum があってもメソッドが混ざらない
• 大規模アプリや User モデルみたいに複数の状態を enum 管理する場合に便利
まとめ
• enum で状態管理するとメソッドが自動生成されて便利
• Rails 8 以降は 新シンタックス一択
• データの整合性を守るために「順番変更禁止」「末尾追加」が鉄則