LoginSignup
2
0

More than 3 years have passed since last update.

素人とEnumerizeとarray: true

Posted at

はじめに

 先日、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(', ')

おわり

 今回の記事におけるミスやもっと良い実装があれば気軽に教えてください!

参考

Enumerizeのドキュメント

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0