0
0

More than 3 years have passed since last update.

Railsのenumの可読性をあげる

Last updated at Posted at 2021-02-28

はじめに

Rails(ActiveRecord)でenumを扱おうとすると、db上のデータはintegerとして扱うことが多いと思います。
しかしこれだとdb上のデータが何を意味しているかわかりづらく、可読性が下がります。
そこで今回はMySQLを使うことを前提に、MySQLのENUM型を定義する方法をメモしておこうと思います。

環境

ruby 3.0.0
rails 6.1.1
MySQL 5.7

手順

class CreateAnimals < ActiveRecord::Migration[6.1]
  def change
    create_table :animals do |t|
      t.string :name
      t.column :animal_type, "ENUM('dog', 'cat', 'bird')", null: false

      t.timestamps
    end
  end
end

t.column :animal_type, "ENUM('dog', 'cat', 'bird')", null: false
この部分で定義しています。
t.columnでMySQLのENUM('dog', 'cat', 'bird')という構文を直接実行できます。

途中からカラムを追加するには少し工夫が必要です。
change_tableで追加できますが、rollbackできないのでdef upで定義しましょう。

class ChangeAnimals < ActiveRecord::Migration[6.1]
  def up
    change_table :animals do |t|
       t.column :animal_type, "ENUM('dog', 'cat', 'bird')", null: false
    end
  end

  def down 
    remove_column :animals, :animal_type
  end
end

途中でENUMを拡張

class ChangeAnimals < ActiveRecord::Migration[6.1]
  def up
    change_table :attendance_punches do |t|
      t.change :animal_type, "ENUM('dog', 'cat', 'bird', 'fish')", null: false
    end
  end
end

ENUMの型を増やすことはできますが、減らしたり、名称を変更しようとするとエラーになるので注意が必要です。
→すでに該当のENUMを持つデータが存在する場合に、そのENUMの種類を消すことはできないようです。(例:animal_type: dogを持つデータが存在した場合、dogを消すようなスキーマ変更はできない。)

enumerizeも使えます

animal.rb
class Animal
  extend Enumerize

  enumerize :animal_type, in: [:dog, :cat, :bird],
                          predicates: true,
                          scope: true
end
animal = Animal.new

animal.dog?   # => false
animal.cat? # => false

animal.animal_type = 'dog'

animal.dog?   # => true
animal.cat? # => false

Animal.with_animal_type(:bird)
# SELECT "animals".* FROM "animals" WHERE "animals"."animal_type" IN ('bird')

おわりに

カラム名をtypeにしたらエラーが出てmigrateできませんでした。どうやら予約語になっているらしく、typeをカラム名にすることはできないようです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0