ガラシのパルプンテ頼み

地方産限界エンジニアのグローバル独り言

【5分くらいでわかる】 enumの使い方 | Rails入門

enumとは

enumとは一つのカラムに指定した複数個の整数の定数に、それぞれ名前を割り当てるために使われるデータ型です。 広義の意味では enumeration: 列挙型 と訳されます。enumを使うメリットとしては以下のようなものが挙げられます。

  • 意味のある単語を用いてデータを操作できるため整数による操作に比べて意味を理解しやすい
  • 開発者が整数の定数とそれぞれの振る舞いとの組み合わせを覚えておく必要がなくなるため可読性とメンテナンス性が上がる
  • enumの定義により動的に定義されるヘルパーメソッドを使うことでコードの記述量を減らすことができる

それでは具体的な例を挙げながらRailsにおけるenumの使い方を追っていこうと思います。

DBにenumで管理したいカラムを作成する

投稿モデルを持つRailsアプリを例に考えてみます。投稿レコードは一件ずつ以下のような状態を持つこととします。

定数 名前 状態
1 draft 下書き
2 public 公開
3 private 非公開
4 trashed ゴミ箱

マイグレーションは以下の通りです。

# db/migrate/yyyymmddhhmmss_create_posts.rb
class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.string :name, null: false
      t.text :description
      t.integer :status, null: false, default: 1

      t.timestamps
    end
  end
end

enumを定義する

rails db:migrateでマイグレーションを実行したら、以下のコード例のようにPostモデルにてenumメソッドを使いenumを定義します。 enumメソッドの第1パラメータにはカラムの属性名を渡し、第2パラメータにはpostのステータスとして利用したい名前のリストを渡します。

# app/models/post.rb

class Post < ApplicationRecord
  enum :status, { draft: 1, public: 2, private: 3, trashed: 4 }
end

enumのヘルパーメソッド

冒頭でenumを定義するメリットとして、enumの定義により動的にヘルパーメソッドが作成されることについて触れたかと思います。 以下にそのメソッドを使ってどのようなことができるのかをシーンに合わせて説明していきます。

ステータスの一覧、または一部を取得する

Post.statuses
#=> { "draft" => 1, "public" => 2, "private" => 3, "trashed" => 4 }

Post.statuses[:draft]
#=> 1

Post.statuses["private"]
#=> 3

特定のステータスを持つレコードを検索する(スコープとして用いる)

Post.private
#=> =>   Post Load (0.4ms)  SELECT "posts".* FROM "posts" WHERE "posts"."status" = $1  [["status", 3]]
[#<Post:0x0000aaaaeb408e90 id: 1, name: 'test_post', description: 'hoge', status: 3>]

ステータスの照合を行う

例えば post.status == 'draft' のような照合は以下のような?付きのメソッドで置き換えられる。

post.draft?
#=> true

post.public?
#=> false

ステータスの更新を行う

更新に関しても以下のようなコードは!付きのメソッドで置き換えることができる

post.status = 'public'
post.save
post.public!