この記事でわかること
- Ruby on RailsでDBをpostgresql利用で開発する際に、PostgreSQLのEnumを利用する方法
- 結論からいうと
gem 'activerecord-postgres_enum'
を利用します。
- 結論からいうと
まえおき
- Ruby on RailsでEnumを扱おうと思ったときに一番に思いつくのは
ActiveRecord::Enum
です。 - この
ActiveRecord::Enum
はActiveRecordがDBにINSERT or DELETEする際に、定義したEnumの文字列から整数値に変換して保存させるといった使い方が一番使われると思います - ただ、DBで実際のデータを見たときに、
1
とか2
が入っていてActiveRecordを介さないと一体何を表しているのかわからないので、PostgreSQLのEnumの機能を利用してデータの見やすさ改善を行っていきます。
手順
手順は簡単、まずはgemを入れましょう\(^o^)/
社員テーブルの性別と血液型の項目にEnumを利用してみます。
テーブル作成
-
Gemfileに
gem 'activerecord-postgres_enum'
を追加するGemfile.rb# その他の部分は省略 gem 'activerecord-postgres_enum'
-
例の如く
bundle install
実行してください -
migrationファイルを作成していきます
-
create_enum
がポイント
20211212174036_create_employees.rbclass CreateEmployees < ActiveRecord::Migration[5.2] def change # 作成するenumを宣言 create_enum :empooyee_gender, %w(male female other) create_enum :empooyee_blood_type, %w(a b o ab) create_table :employees do |t| t.string :name, null: false # 各カラムに上記で宣言したenumを指定する t.enum :gender, enum_name: :employee_gender t.enum :blood_type, enum_name: :employee_blood_type t.timestamps end end end
-
-
bundle exec rails db:migrate
でテーブルを作成しましょう -
gender
,blood_type
にenumが適用されていることを確認します(下記はTablePlusを使って確認しています)
ActiveRecord
から、作成したenumを扱う
- ModelにEnumを宣言します
- 基本的にはいつもと同じですが、value値に対応する文字列を指定します
employee.rb
class Employee < ApplicationRecord
enum gender: {
male: 'male',
female: 'female',
other: 'other'
}
enum blood_type: {
a: 'a',
b: 'b',
o: 'o',
ab: 'ab'
}
end
- このようにすることで、いつもの
ActiveRecord::Enum
と同じ用に扱うことができます
お疲れさまでした。
あとがき
- 個人的にはEnumを使うときは整数値を保存せずに、上記のように文字列でデータが保存されることでデータの見やすさが圧倒的に違うので、どんどん利用していきたいと思っています。
- 整数として保存されると実装を追わないと何を示しているのかわからない
- 特にAPIの開発をしていると辛い部分があります...
- また、今回記事にした理由として、gemを使わずにenumを作成しようとした際に下記のデメリットが有りました
- migrationファイルにSQLを直接書くことになり、せっかくrailsを使っているのに...という気分になる(w)
- テーブル自体は作成できるが、
schema.rb
にスキーマが正しく追加されず下記のように省略されてしまう
schema.rb
# Could not dump table "employees" because of following StandardError
# Unknown type 'employee_gender' for column 'gender'
- こういった理由から今回は
gem 'activerecord-postgres_enum'
を採用しました。
なにかありましたらコメントいただければと思います。