enumを利用したプルダウン選択機能の実装方法

f:id:ryoutaku_jo:20190206203052p:plain

【結論】
enumとは、整数が割り当てられた文字を順番に出力する機能

ActiveRecordの機能の一つで、
 文字に対して数値を割り振る処理は、モデルに記述する

都道府県など、特定の選択肢からプルダウンで選択する
 フォームなどを作成する際に活用される。

・モデルに定義の追加削除を行う場合、
 既にデータベースへ登録されている情報と
 整合性が取る必要がある


【目次】


【本題】

都道府県のプルダウン選択機能の実装

チーム開発で都道府県を選択できる機能を実装する事になったのですが、
HTMLに候補を全て記述すると、かなり記述量が多くなってしまうので、
enumを使った実装を試しました。

enumとは

列挙型と呼ばれるもので、
整数が割り当てられた文字を順番に出力する機能です。

RailsではActiveRecordの機能の一つで、
モデルで列挙したい文字に整数を割り振ることで、
データベースに数値で保存されたデータを、
プログラム上では文字として扱うことが可能となります。

実装方法

1:都道府県の情報を登録するカラムを作成する(integer型)

今回はUserテーブルに、都道府県の情報を登録する「prefecture」カラムを作成します。
その際、数値で登録をするので、integer型でデータベースを作成します。
マイグレーションファイルは下記のように記述します。

t.integer :prefecture,    null: false, default: "0"


2:modelにenumの定義を記述する

userモデルに、enumで割り振る整数と文字を定義します。
具体的な記述方法は下記の通りです(他の記述方法もありますが、後述)

  enum prefecture: {
    "--未選択--":0,北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
    茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
    新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
    岐阜県:21,静岡県:22,愛知県:23,三重県:24,
    滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
    鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
    徳島県:36,香川県:37,愛媛県:38,高知県:39,
    福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  }


3:「from_for」内に「f.select」でenumの情報を表示させる

enumの情報を、プルダウンで選択できるようにするには、
userモデルオブジェクトをセットした「from_for」内に
「f.select」を記述します。記述例は下記の通りです。

= form_for(resource, as: resource_name, url: registration_path(resource_name), :html => {:class => "new_user_signup"}) do |f|

##中略##

.input-form__name 都道府県
.input-form__icon 必須
%br/
.input-form__form
  = f.select :prefecture, User.prefectures.keys, {prompt: '選択してください'}, class: 'signup_input signup_input--prefecture error-form--prefecture'

##中略##


そして実際に実装した物が下記になります。

f:id:ryoutaku_jo:20190206214145p:plain

f:id:ryoutaku_jo:20190206214201p:plain

enumの様々な書き方

先ほど後述すると説明した、他の記述方法についてです。
モデルにenumを定義する記述方法は、下記の三種類が存在します。


・Integer

前項でも取り上げた、各文字に直接番号を割り当てる方法です。

  enum prefecture: {
    "--未選択--":0,北海道:1,青森県:2,岩手県:3,
  }

メリット:どの文字が何番か分かりやすい
デメリット:途中から挿入が容易


・Article

下記の様に配列形式で記述する事も可能です。

  enum prefecture: [
    :"--未選択--",:北海道,:青森県,:岩手県
  ]

メリット:途中から挿入が容易
デメリット:何番がどれか分かりづらい


・boolean

ブーリアン型とは、「真 = true」と「偽 = false」の二種類だけのデータ型ですが、
これで表す事も可能です。

  enum prefecture: { 
    draft: false, published: true
}

メリット:選択肢がture/falseのみで明瞭
デメリット:ture/false以外の選択肢を増やせない


実装後の注意点

enumは値を自動的に割り当てて、データベースに保存を行うので、
値が重複することがありませんが、途中で定義を修正してしまうと、
今まで登録してきた数値と整合性が取れなくなる可能性があります。

なので、定義を変更する際は、
今までのデータに対応する数値が変わらない様にする必要があります。

総括

相変わらずActiveRecordの機能ということで、
ActiveRecordには未知の領域が大き過ぎると
改めて実感しました。

《今日の学習進捗》

チーム開発:12日目
ユーザー新規登録のバリデーションを記述。

学習開始からの期間 :61日
今日までの合計時間:627h
今日までに到達すべき目標時間:557h
目標との解離:70h
「10,000時間」まで、

残り・・・「9373時間!」