SakuraWi - BLog

みんなのウェディングのエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

【Ruby on Rails】enumとは?enumを使って可読性をあげてみよう


ども、櫻井広大です。

enumについて書いてみようと思います。 enumは使ってみると僕は便利だと思っているのですが、初学者からすると、一体これはどうやって使うんだ?とか、ちょっと抵抗があるなじゃないかと思ってまして

そのハードルのようなものが取っ払うことができればと思って書いています。

enumとは

enum(イーナム)とは、列挙型のことです。

列挙型については以下wikipediaからの引用です。

列挙型とは、コンピュータプログラミングにおいて、プログラマが選んだ各々の識別子をそのまま有限集合として持つ抽象データ型である。

ざっくりというと整数の値に意味づけを行うイメージです。

複数の定数をまとめて指定できます。

使用例

例をみた方が早いと思うので、例を書きます。

DBのarticlesというテーブルがあったとして、そのカラムにstatusカラムが存在するとします。

そのstatusはinteger型として、

0の値が入っている時を下書きの状態、 1の値が入っている時を公開中の状態、 2の値が入っている時をアーカイブの状態 といったように運用するとします。

その際にコードで表現する時に0,1といった数値ではなく文字列で扱えるようにします。

そうすることで、「この数値の意味ってなんだっけ?」ということを防止できます。

Ruby on Railsにおけるenumの定義の仕方

enum status: { draft: 0, published: 1, archived: 2 }

上記のようにclassの中で利用すればOKです。

ちなみにenumはApplicationRecordに定義してあるため、こちらを継承していると利用できますが、ApplicationRecordではないclassでは利用できないので注意しましょう。

Ruby on Railsのenumは便利なメソッドが生えるぞ!

enumを定義するといろんな便利なメソッドが利用できるようになります。

仮に下記のようなmodelがあったとします。

class Article < ApplicationRecord
  enum status: { draft: 0, published: 1, archived: 2 }`
end

scopeチックな利用が可能

Article.draftでdraft状態にあるレコード( statusが0のレコード)が取得できます。

インスタンスメソッドでオブジェクトの状態を知ることができる。

@article = Article.find(1)
@artcile.published?

定義したenumの文字列に?をつけてメソッドを呼ぶことで中身が一致していれば、trueが、一致していなければfalseが返ってきます。

余談

Ruby on Railsは6からenumを定義すると、scopeに自動的に not_xxxが追加されるようになりました。

enum status: { draft: 0, published: 1, not_published: 2 }と定義していたり、scopeに同様の名前のものが定義してあると予期せぬ挙動になる可能性があるので注意が必要です。

enumのメリット

個人的にenumのメリットは可動性とメンテナンスのしやすさにあるかなと思います。 第三者がみた時にDBの中身やドキュメントを読まずにそのカラムが持ち得る数値、意味が伝えることができるので、そこがメリットではないかと思っています。