【Rails】 enumとは? enumを用いてselectボックスを作ってみた


はじめに

業務の際、Railsのモデル内でよく見かけるenum
何となく便利そうとは思っていたものの、使い方がイマイチわかっていなかったのでまとめてみます。

enumとは

・日本語に訳すと「列挙型」というらしい。
・DBにはint型やboolean型で登録され、数値に対応する任意のキー名を付けることができる。
・アプリケーション側のソースコードでは、付けたキー名を用いることができる。

どんなときに使う?

特定のカラムで用いる固定値がある程度決まっている際に用いると良いそうです。
例えば、有効無効などの状態を保存しておくカラム(statusはよく見かけます)など、選択肢の数が決まっている場合に用います。

実際に使ってみる

今回は本のタイトル、概要、本のカテゴリーを登録するフォームを作ります。
ジャンルはenumを用いて登録します。

migrationファイル作成

まずはrails g migration create_booksでmigrationファイルを作成します。
migrationファイルの中身はこのように記載。

201907120725_create_books.rb
class CreateBooks < ActiveRecord::Migration[5.2]
  def change
    create_table :books do |t|
      t.string :title, null: :false
      t.string :overview, null: :false
      t.integer :genre, null: :false, limit: 1

      t.timestamps
    end
  end
end

ジャンルは数値でDBに登録されるため、今回はint型です。
rails db:migrateでDBを作成。

モデルにenumを書いていく

bookモデルにenumを書きます。
enum カラム名:{付けたいキー名:対応する数値}でenumを指定していきます。

book.rb
class Book < ApplicationRecord
  enum genre:{
    nobel: 0, #小説
    essay: 1, #エッセイ
    practical: 2, #実用
    comic: 3, #漫画
    other: 4 #その他
  }
end

以上でenum指定は完了。

enumで使用できるメソッド

enumで設定したキー名を用いて、book1のジャンルを登録してみる

rails cでコンソールを起動し、book1を作成。

book1 = Book.create(title:'book1', overview:'sample', genre: :comic)
   (0.0ms)  begin transaction
  Book Create (0.5ms)  INSERT INTO "books" ("title", "overview", "genre", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["title", "book1"], ["overview", "sample"], ["genre", 3], ["created_at", "2019-07-12 08:36:47.823960"], ["updated_at", "2019-07-12 08:36:47.823960"]]
   (0.6ms)  commit transaction
=> #<Book id: 1, title: "book1", overview: "sample", genre: "comic", created_at: "2019-07-12 08:36:47", updated_at: "2019-07-12 08:36:47">

ジャンルをキー名で指定することができました。数値で指定することもできますが、どの数値が何を指しているのかわからなくなりそうなのでenumの方が便利です。

book1のジャンルがcomicか確かめてみる
book1.comic?
=> true
book1.nobel?
=> false

.キー名?で真偽値が返ってきます。

book1のジャンルを変更してみる
book1.essay!
   (0.1ms)  begin transaction
  Book Update (11.4ms)  UPDATE "books" SET "genre" = ?, "updated_at" = ? WHERE "books"."id" = ?  [["genre", 1], ["updated_at", "2019-07-12 08:47:00.093188"], ["id", 1]]
   (0.6ms)  commit transaction
=> true

.キー名!でジャンルが変更できました。

book1の現在のジャンルは何か確認する
book1.genre
=> "essay"

enumを設定していないカラムと同様、.カラム名で確認できます。

if文でenumを使ってみた

いくつかbookのデータを保存し、ジャンルがessayの時だけ文章を出力します。

def confirm_essay
  books = Book.all
  books.each do |book|
    if book.essay? 
      puts "#{book.title}はエッセイです"
    end
  end
end
#confirm_essayを呼び出した結果
book1はエッセイです

条件分岐の際にもキー名をそのまま使えるのは良いですね。

enumを用いてselectボックス作成

register.html.erb
 <%= select :genre, :name, Book.genres.keys.to_a, include_blank: true %>

erbファイルにこのように書き、できたselectボックスはこちら。

enumで設定したキー名が選択できるようになりました。
モデル名.カラム名複数形.keysで設定したenumを呼び出しています。

おわりに

自分なりにenumについてまとめてみました。
初心者ですので、間違っている点等あればご指摘いただけますと幸いです。

参照元:https://ruby-rails.hatenadiary.com/entry/20150710/1436461745