enum型または列挙型とは、複数の変数をまとめて管理するためのデータ型のことです。
int型やstring型などに比べるとあまり聞きなれないかもしれませんが、非常に便利な型です。
この型は文字列として扱いたいものをデータベースには数値として保存しておくというものです。
ActiveRecordのEnumを使用することで、データベースの数値型カラムと任意の文字列を紐づけることができます。
Railsに組み込まれたEnum以外にも、enumerizeを利用することでより柔軟な処理ができるようになります。
オンラインでプログラミング学習を始めてみたいなら、米国シリコンバレー発祥の世界最大級のオンライン学習プラットフォーム、Udemyがおすすめです。
こちらの記事で紹介するフレームワーク、Ruby on Railsも学ぶことができます!
よくわかるRuby on Rails入門 オンライン講座
enum型とは
enum型の使いどころは様々ですが、どのような場面で力を発揮するかは例を見てみるとすぐにわかります。
たとえば、データベースのテーブルに性別データを保存するカラムがあったとします。
性別は一般的に「男性」、「女性」、「その他」の3つに大別されます。
これらに対して男性=1、女性=2、その他=3とそれぞれ対応した数値を割り当てておきます。
データベース上では数値として情報を保存し、これらをアプリケーション層で文字列に対応付けすることができれば、数値データを文字列として扱うことができます。
そういった機能をサポートしてくれるのがenum型です。
Ruby on Railsではデフォルトで用意されているActive Recordの機能としてEnumがあります。
また、より柔軟な処理ができるように開発されたenumerizeというサードパーティのパッケージもよく使われます。
enum型を利用することで、コードの柔軟性や保守性が向上するという利点があります。
開発の途中で使用する文字列を変更したくなった場合でも、データベースに保存されているのは数値なので、それまでのデータへの影響が全くありません。
また、設定してある値以外は基本的に保存できないようにするため、予期しないデータが混在することを防げます。
必ず利用しなければいけないというものではありませんが、意外と活用できる機会が多いので身につけておいて損はないでしょう。
ここからはイベント管理アプリを作ってenum型の使い方を紹介していきます。
同じ環境で試してみたい方は、以下に従ってコマンドを実行しておいてください。
# 新規プロジェクトの作成
$ rails new event-app
$ cd event-app
# scaffoldコマンドでEventモデル周りのファイルを自動生成
$ rails generate scaffold event name:string hold_date:date
# データベースの作成
$ rails db:create
# マイグレーションの実行
$ rails db:migrate
Enumの使い方
enum型の設定
まずはイベントに関するデータを扱うEventモデルに対して開催状況を管理するカラム(status)を追加してみます。
マイグレーションファイルを生成しましょう。
$ rails generate migration AddStatusToEvents
マイグレーションファイルを開き、以下のようにカラムを追加することを記述します。
適用したいデータベースのカラムは数値型にしておきます。
class AddStatusToEvents < ActiveRecord::Migration[6.1]
def change
add_column :events, :status, :integer, null: false
end
end
忘れずにマイグレートも実行します。
$ rails db:migrate
カラムが追加できたら、モデル(Active Record)の中に数値と文字列の対応関係を記述します。
名称(シンボル名)と数値の組み合わせは、ハッシュ(連想配列)の形式で定義しておきます。
class Event < ApplicationRecord
enum status:
{
scheduled: 0,
rehearsal: 1,
in_sesson: 2,
archive: 3,
cancel: 4,
}
end
レコードの登録
レコードを登録してenum型の挙動を確認してみます。
以下の例では、statusというカラムに対して scheduled
という文字列を指定していますが、発行されたSQLを見てみると数値型の0が保存されているのがわかります。
このことからも、Railsのモデル(Active Record)が数値と文字列を対応付ける橋渡しをしてくれていることがわかります。
$ rails console
irb(main):001:0> event = Event.new
(0.6ms) SELECT sqlite_version(*)
=> #<Event:0x00000267d7975b58 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil, status: nil>
irb(main):002:0> event.name = 'sample event'
=> "sample event"
irb(main):003:0> event.hold_date = Time.parse('20230101')
=> 2023-01-01 00:00:00 +0900
irb(main):004:0> event.status = 'scheduled'
=> "scheduled"
irb(main):005:0> event.save
TRANSACTION (0.1ms) begin transaction
Event Create (0.8ms) INSERT INTO "events" ("name", "hold_date", "created_at", "updated_at", "status") VALUES (?, ?, ?, ?, ?) [["name", "sample event"], ["hold_date", "2023-01-01"], ["created_at", "2021-11-08 23:10:00.978056"], ["updated_at", "2021-11-08 23:10:00.978056"], ["status", 0]]
TRANSACTION (2.3ms) commit transaction
=> true
また、enum型のカラムはそもそも数値型と変わらないので、数値を指定してレコードを保存することもできます。
$ rails console
irb(main):001:0> event = Event.new
(0.9ms) SELECT sqlite_version(*)
=> #<Event:0x000001ec737ec140 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil, status: nil>
irb(main):002:0> event.name = 'sample event 2'
=> "sample event 2"
irb(main):003:0> event.hold_date = Time.parse('20230501')
=> 2023-05-01 00:00:00 +0900
irb(main):004:0> event.status = 0
=> 0
irb(main):005:0> event.save
TRANSACTION (0.1ms) begin transaction
Event Create (0.9ms) INSERT INTO "events" ("name", "hold_date", "created_at", "updated_at", "status") VALUES (?, ?, ?, ?, ?) [["name", "sample event 2"], ["hold_date", "2023-05-01"], ["created_at", "2021-11-08 23:17:45.120039"], ["updated_at", "2021-11-08 23:17:45.120039"], ["status", 0]]
TRANSACTION (2.9ms) commit transaction
=> true
enumの参照と更新
先ほど保存したレコードを取得してenum型のカラムを参照すれば、シンボル名(数値に対応した文字列)が確認できます。
さらに、before_type_castでデータベースに保存されている実際の数値を確認することもできます。
$ rails console
irb(main):001:0> event = Event.find(1)
(0.5ms) SELECT sqlite_version(*)
Event Load (0.2ms) SELECT "events".* FROM "events" WHERE "events"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<Event:0x000001d6d9aa1868 id: 1, name: "sample event", hold_date: Sun, 01 Jan 2023, created_at: Mon, 08 Nov 2021 23:10:00.978056000 UTC +00:00, updated_at: Mon, 08 Nov 2021 23:10:00.978056000 UTC +00:00, status: "scheduled">
irb(main):002:0> event.status
=> "scheduled"
irb(main):003:0> event.status_before_type_cast
=> 0
enumのシンボル値に?を付けたメソッドを用いると、状態を確認できます。
enumのシンボル値に!を付けたメソッドを用いると、状態を更新できます。
カラムの内容を簡単に更新できるので、非常に便利ですね。
irb(main):004:0> event.scheduled?
=> true
irb(main):005:0> event.archive?
=> false
irb(main):006:0> event.rehearsal!
TRANSACTION (0.1ms) begin transaction
Event Update (0.9ms) UPDATE "events" SET "updated_at" = ?, "status" = ? WHERE "events"."id" = ? [["updated_at", "2021-11-08 23:21:19.812699"], ["status", 1], ["id", 1]]
TRANSACTION (22.4ms) commit transaction
=> true
irb(main):007:0> event.scheduled?
=> false
irb(main):008:0> event.rehearsal?
=> true
データベースの確認
enum型のカラムが実際に数値で保存されていることを確認してみましょう。
$ rails dbconsole
SQLite version 3.35.2 2021-03-17 19:07:21
Enter ".help" for usage hints.
sqlite> SELECT name, status FROM events;
sample event|1
sample event 2|0
シンボル値の日本語化
プログラムは基本的にすべてアルファベットで記述し、処理中に日本語を混在させることを防ぎます。
これは、プログラムが文字列を2進数に変換(エンコード)して処理する際のエンコーディング方式などで問題が発生しやすいためです。
そのためenum型のシンボル名を日本語に対応させるには、i18nとenum_helpのパッケージを使用します。
ちなみにi18nとは国際化を意味する英単語である「internationalization」を省略したものです。
18はiとnの間に18個のアルファベットがあることを意味しています。
Gemfileに以下のrails-i18nとenum_helpを追加し、パッケージをBundlerでインストールします。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.2'
gem 'rails-i18n'
gem 'enum_help'
...
$ bundle install
次にconfig/application.rbの設定を書き換え、使用するロケール(言語)をjaに変更します。
...
module EventApp
class Application < Rails::Application
config.load_defaults 6.1
config.i18n.default_locale = :ja # この行を追加
end
end
さらにconfig/localesフォルダの中にja.ymlを作成し、以下のように記述します。
ここではモデル名ごとに指定していますが、代わりにdefaultを使用すればアプリ内全体で値を共有できます。
以下の例でいえば、3行目の event
の部分を default
に書き換えれば大丈夫です。
ja:
enums:
event:
status:
scheduled: '開催予定'
rehearsal: 'リハーサル中'
in_session: '開催中'
archive: '開催終了'
cancel: 'キャンセル'
日本語化されたことを確認してみます。
言語ファイル(ja.yml)を適用後の値を取得するには、カラム名_i18n
を参照します。
irb(main):001:0> event = Event.find(1)
(0.9ms) SELECT sqlite_version(*)
Event Load (0.3ms) SELECT "events".* FROM "events" WHERE "events"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<Event:0x0000022cccf24f40 id: 1, name: "sample event", hold_date: Sun, 01 Jan 2023, created_at: Mon, 08 Nov 2021 23:10:00.978056000 UTC +00:00, updated_at: Mon, 08 Nov 2021 23:21:19.812699000 UTC +00:00, status: "rehearsal">
irb(main):002:0> event.status
=> "rehearsal"
irb(main):003:0> event.status_i18n
=> "リハーサル中"
RubyのフレームワークといえばRuby on Railsです。
そもそもフレームワークとは何かということから、Ruby on Railsの基本理念や設計思想まで、プログラミング未経験の方にもわかりやすくご紹介!
また、インストール方法から最初の画面を表示するまでの流れについても解説しています。
現場を意識した本格的な学習カリキュラムで、本物のスキルを身につけたいならこちら!
困ったときにいつでも相談できるバディ制度でわからないこともすぐに解決できます。
プログラミングスクールといえば【RUNTEQ】
enumerizeの使い方
gemパッケージのインストール
EnumはRailsでデフォルトのenum型を利用するためのものでした。
Gemパッケージのenumerizeは、さらに柔軟に高機能なenum型を利用したい場合によく使われます。
利用するにはまずGemfileにenumerizeを追加し、パッケージをインストールします。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.2'
gem 'enumerize'
...
$ bundle install
enum型の設定
enum型の定義の仕方は以下の通りで、Railsのデフォルト機能のEnumとほぼ同じような記述方法となっています。
extendでEnumerizeのモジュールを取り込んでおくのを忘れないようにしましょう。
以下のようにデフォルト値を指定することもできます。
class Event < ApplicationRecord
extend Enumerize
enumerize :status, in:
{
scheduled: 0,
rehearsal: 1,
in_session: 2,
archive: 3,
cancel: 4,
},
default: :scheduled
enumrizeでシンボル名を日本語化するには、先ほど紹介したconfig/locales/ja.ymlの”enums”の部分を”enumrize”に書き換えます。
ja:
enumerize:
event:
status:
scheduled: '開催予定'
rehearsal: 'リハーサル中'
in_session: '開催中'
archive: '開催終了'
cancel: 'キャンセル'
enumの参照
enumrizeによるenum型データの参照方法は以下の通りです。
$ rails console
irb(main):001:0> event = Event.find(1)
(1.1ms) SELECT sqlite_version(*)
Event Load (0.2ms) SELECT "events".* FROM "events" WHERE "events"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=>
#<Event:0x0000019d48bc3608
...
irb(main):002:0> event.status
=> "rehearsal"
irb(main):003:0> event.status_value
=> 1
irb(main):004:0> event.status_text
=> "リハーサル中"
さらに詳しいenumrizeの使い方はこちらです。
まとめ
enum型はデータベースのレコードの状態を表す情報の扱いをサポートしてくれます。
アプリケーション上では文字列として、データベース上では数値として、主に状態を表すときによく用いられます。
まずは基本的なEnumの使い方を身につけ、要件に応じてenumerizeなどのパッケージを利用するようにしましょう!
ひとりではなかなかプログラミングの学習が続かない、未経験だから不安が多い、という方はプログラミングスクールを利用してみるのも有効です。
本物のエンジニアに学ぶことで、時間がない方でも最短でスキルを身につけることができます。
現役エンジニアのパーソナルメンターからマンツーマンで学べる
お悩みの方は、まずは無料キャリアカウンセリングにお申込みください。
関連記事
RubyのフレームワークといえばRuby on Railsです。
そもそもフレームワークとは何かということから、Ruby on Railsの基本理念や設計思想まで、プログラミング未経験の方にもわかりやすくご紹介!
また、インストール方法から最初の画面を表示するまでの流れについても解説しています。
早速Ruby on RailsでWebアプリケーションを作ってみたい方必読!
初心者の方でも挫折することなく、コマンド一発でToDoアプリを完成させることができる方法をご紹介。
Railsを学び始めようと思っている方から、フレームワークについて学びたいけどいまいちメリットがわからない方まで、ぜひ一度お試しください!
Ruby on Railsなどの多くのフレームワークが採用しているMVCアーキテクチャにおいて、データベースとのやり取りを引き受けているのがモデルです。
RailsではActive RecordというORMが使われており、データベースのデータをオブジェクト指向に対応させて取り扱うことができます。
Active Recordの使い方をマスターして、Railsへの理解を深めましょう!
多くのWebアプリで一般的に利用されているリレーショナルデータベースでは、複数のテーブルを関連付けることができます。
Ruby on RailsのORMであるActive Recordにも、モデル同士のリレーションを表現するためのアソシエーションという機能があります。
アソシエーションをマスターして、より複雑なデータベース設計を身につけましょう!
Webアプリケーションでユーザが入力されたデータが正しい形式であるかを確かめるには、バリデーションチェックを行います。
またデータに誤りがあれば、それをユーザに伝えて再度値を入力し直してもらう必要があります。
バリデーションの実装方法とエラーメッセージの日本語化を身につけましょう。
Ruby on RailsはMVCアーキテクチャを採用しており、リクエストを受けてからレスポンスを返すまでのライフサイクルを理解しておくことは非常に重要です。
この流れをしっかり学んでおくだけで、驚くほどアプリケーション開発がしやすくなります!
コメントを書く