はじめに
都道府県などのプルダウンメニューを作成する際、enumを使いました
これを使うことで都道府県などのデータをわざわざテーブルとして用意する必要がなくなります
便利だったのですが、DBへの保存の際に型が合わないなどの問題も発生したのでまとめておきます
環境
Ruby: 2.5.1
Rails: 5.2.4
実際の操作
実際の操作は以下のようになります
- 該当カラムをinteger型で作成
- モデルにプルダウンメニューで表示させるもの一覧を記載
- ビューで表示させるプルダウンの記述
- 入力したフォームの受け取り型を編集
1. 該当カラムをinteger型で作成
下記の場合は都道府県です
t.integer :prefecture, null: false
#### 2. モデルにプルダウンメニューで表示させるもの一覧を記載
enum prefecture: {
北海道: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. ビューで表示させるプルダウンの記述
= form.select :prefecture, Address.prefectures.keys, {prompt: "選択してください"}, class: "prefecture-select"
これでプルダウンメニューとして表示することはできるようになったんですが、binding.pryでparamsの中を見てみると"北海道"として値を取得してきてしまいました。
prefectureカラムはinteger型なのでこのままだとDBに登録できなくて困ります。
4. 入力したフォームの受け取り型を編集
色々調べた結果、以下のようにすると対応するvalueの値を取得できることがわかりました。
= form.select :prefecture, options_for_select(Address.prefectures), {prompt: "選択してください"}, class: "prefecture-select"
しかし、これだと"1"という文字列なのでまだカラムに登録できません。
form.selectにおける入力値を数値として送れないかと思いましたが、やり方がわからなかったので、受け取る側で無理矢理数値型に変換することにしました。少々かっこ悪いですが、ストロングパラメータで数値型にした後にmergeしてます。
def address_params
params.required(:address).permit(:postal_code, :city, :street, :building).merge(prefecture: params[:address][:prefecture].to_i)
end
これで晴れてDBへ保存できるようになりました
ただもっとスマートな方法がありそうな気がしてます
何か知ってる方いらっしゃいましたら教えていただけると嬉しいです
似たようなものにactive_hashというものがあります
gemをインストールする必要がありますが、こちらは数値型としてデータを取得できますし、ActiveRecordのメソッドも使えるみたいなので便利そうです