はじめに
先日、Railsでチェックボックスを使った複数選択を実装した際に詰まったところがあったので書いておきます。
やりたかったこと
- 好きな果物
- みかん
- りんご
- ぶどう
- バナナ
選択肢の要素はEnumerizeで管理し、ビュー側では上のように複数選択でき、String型でDBに保存し、CSVで出力する際に"りんご, バナナ"という形式にする。
詰まったところ
CSVに出力しようとするとnilが返ってきた。
解決法
以下のようにマイグレーションファイルでarray: true
を追加する。
def change
add_column :users, :favorite_fruits, :string, array: true
end
原因
複数選択の際にEnumerizeは配列を返す(#<Enumerize::Set {apple, banana}>
)ので、array: true
の指定によって配列を許容しておかないとDBに保存できなかったのではないか(おそらく)。
おまけ
今回使ったRailsで複数選択をする実装をついでに書いておきます。いろんな実装があると思うので個人の責任でお願いします。ちなみに、カラムに複数値を入れるのはアンチパターンです(『SQLアンチパターン』の最初に出てきたような気がする)。ご利用は計画的に!
model
class User < ActiveRecord::Base
extend Enumerize
enumerize :favorite_fruits,
in: %i[
orange
apple
grape
banana
], multiple: true
end
end
view
<%= form_for @user do |f| %>
<% User.favorite_fruits.options.each do |name, value| %>
<%= f.check_box :favorite_fruits, { id: "user_favorite_fruits_#{value}", multiple: true } %>
<%= f.label :favorite_fruits, name, value: value %>
<% end %>
<% end %>
controller
class User < ApplicationController
def show
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
# 処理省略
end
end
private
def user_params
params.require(:user).permit(favorite_fruits: [])
# ストロングパラメーターの配列のための書き方
end
end
locale
ja:
user:
favorite_fruits:
orange: 'みかん'
apple: 'りんご'
grape: 'ぶどう'
banana: 'バナナ'
csvに出力するとき
@user.favorite_topics.texts.join(', ')
おわり
今回の記事におけるミスやもっと良い実装があれば気軽に教えてください!