こんにちは! フリーエンジニアの長瀬です。
みなさんはenumを使ってますか?
enumには様々なメリットがあるので、使っていない人は一緒に勉強していきましょう。
この記事では、enumの使い方について
・enumとは
という基本的な内容から、
・enumの使い方
・enumのi18n対応とは
といった応用的な内容についても解説していきます。
enumとは
enumは列挙型と訳されます。
列挙とは整数が割り当てられた文字を順番に出力していくことを意味します。
今はなんのことかわからないと思いますが、記事を読むにつれてわかります。
enumを使えば、文字の配列に整数を順番に割り当てられます。
なので、他のプログラマーに読みやすいコードを書くことができます。(可読性が上がる)
たとえば、プログラム内にて都道府県に関する情報を扱う場合、01:北海道、02:青森〜47:沖縄という2桁のコードで表現するよりも、Hokkaido:北海道、Aomori:青森〜Okinawa:沖縄と意味のある単語で表す方がプログラムの可読性が上がります。
また、整数値の範囲が決定されるので誤った数値を使ってしまうことを前もって、防げます。
Railsでは、モデルにenumを定義することで、文字を使ってカラムの値を変更したり、反対に取り出したりできます。
繰り返しになりますが、意味のある単語を使って、操作できるのでプログラマーが開発をしやすくなります。
enumの使い方
では、実際にenumを使っていきましょう。
まずはモデルを作ります。
コマンドプロンプトに以下のコードを入力してください。
rails g model Battle status:integer
これで、整数型(integer)のカラム(status)を持つBattleモデルを定義できました。
また、app/db/migrate/20170629023209_create_battles.rbから先ほど作成したマイグレーションファイルを開いて以下のようにstatusカラムに詳細を加えます。(20170629023209の部分は西暦、月、日、時、分、秒を表しているので、ご自身の環境で作成した日時に依存します。)
def change create_table :battles do |t| t.integer :status,default: 0, null: false, limit: 1 t.timestamps end end
default:0 →初期値を0
null:false →レコードにnullの値を入れることを許可しない
limit: 1 →レコードの数を1個に限定
statusはそのたびに値を更新して使うので、このような制約をしています。
ここまで、入力できたら
rake db:migrate
でマイグレーションの内容をデータベースに反映します。
次にenumの定義です。
app/models/battle.rbに以下のコードを入力してください。
enum status:{attack: 0,spells:1,defend:2,item:3, abilities:4} #atttak=攻撃、spells=魔法、defend=防御、item=アイテム、abilities=特技
これで、enumを定義できました。
次にコントローラーとビューを作ります。
コマンドプロンプトに以下のコードを入力してください。
rails g controller Battle test
これで、コントローラーとビューが作れました。
準備が整ったので、enumを使っていきましょう。
まずはハッシュがしっかりと定義されているかどうかビューにセレクトボックスを配置して確認してみましょう。
app/views/battle/test.html.erbに以下のコードを入力してください
<h1>Battle#test</h1> <%= select :status,:name,Battle.statuses.keys.to_a %> <%= select :status,:name,Battle.statuses.values.to_a %>
Battle.statuses.keys.to_a、Battle.statuses.values.to_aでBattleモデルに定義されたenumを呼び出しています。
コンソールにrails serverを入力し、サーバーを立ち上げた後はapp/config/route.rbを開いてapp/views/battle/test.html.erbを表示するためのルーティングを確認します。
get ‘battle/test’となっているので、http://localhost:3000/battle/testにアクセスします。
実行結果
このように、モデルで定義したenumはビューでも使うことができます。
次にenumのメソッドを紹介します。
rails consoleでコンソールを開いて以下のコードを入力してください。
battle = Battle.new(status: :attack) #statusをattackにする battle.status #現在のstatusを確認する battle.attack? #現在のstatusがattackなのか確認する battle.defend? #現在のstatusがdefendなのか確認する Battle.statuses #モデルで定義したハッシュの中身を確認する Battle.statuses[:item] #ハッシュとして使う、アイテムに定義された整数値は? battle.spells! #statusをspellsに変更する battle.status #現在のstatusを確認する battle.item! #statusをitemに変更する battle.status #現在のstatusを確認する
実行結果
=> #<Battle id: nil, status: "attack", created_at: nil, updated_at: nil> => “attack" => true => false => {"attack"=>0, "spells"=>1, "defend"=>2, "item"=>3, "abilities"=>4} => 3 => true => “spells" => true => "item"
このようにenumには便利なメソッドがたくさん用意されています。
本来、statusをenumにて定義していなければ、battle = Battle.new(status: 0)と実装することになります。この場合"0"が何を意味するのかすぐに判断がつきません。
しかし、サンプルコードの例のように":attack"と書いてあればコードを見ただけでどのような値か直感的にわかりやすくなります。
これがenumのメリットです。
enumのi18n対応とは
i18nとは
i18nはアイエイティーンエヌと読みます。
そして、i18nはソフトウェアを国際化することを意味します。
国際化することによって、より多くの国の人々が利用できるようになります。
ようするに、たくさんの言語に対応して、たくさんの人に使えるようにするということです。
i18n対応の具体的な方法
enumでは文字に整数値を割り当てることによって、プログラマーに理解しやすいように工夫していましたが、中身は英語になっています。(例 attack,defend,item)
ここでは日本語で出力するように国際化してみましょう。
enumを18nに対応させるには、enum_helpというgemを使うとすぐにできます。
まず、Gemfileに以下のコードを入力してください。
gem 'enum_help'
そして、コマンドプロンプトでbundle installを入力して、gemをインストールしてください。
次に、app/config/locals/ja.ymlを作成し、以下のコードを入力してください。
ja: enums: battle: status: attack: 攻撃 spells: 魔法 defend: 防御 item: アイテム abilities: 特技
それでは確認してみましょう。
rails consoleでコンソールを開いた後、以下のコードを入力してください。
battle = Battle.new(status: :attack) #statusをattackにする battle.status #現在のstatusを確認する battle.status_i18n #現在のstatusを日本語に変換して確認する battle.spells! #statusをspellsに変更する battle.status_i18n #現在のstatusを日本語に変換して確認する
実行結果
=> #<Battle id: nil, status: "attack", created_at: nil, updated_at: nil> => “attack" => “攻撃" => true => "魔法"
このように語尾に_i18nをつけることで日本語化されます。
攻撃、魔法と出力されることが確認できました。
enum_helperを使えば、簡単にenumをi18n対応できます。
まとめ
いかがでしたでしょうか?
この記事では、enumの使い方を解説しました。
enumを使えば、数字を意味のある文字として扱えるので、便利です。
使えるところがあれば、積極的にenumを使っていきましょう。
もしenumの使い方について忘れてしまったらこの記事を確認してくださいね!