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!