やりたい事
複数チェックボックスで入力された値をカンマ区切り形式でデータベースへ格納したい。
( 中間テーブルを使った has_many through なアソシエーションを組む方法もあるが、そこまでする必要がないと判断した場合に。 )
テーブルを正規化し、中間テーブルを使った has_many through なアソシエーションを組むのが正攻法だと思うが、こういう事もできますよという参考まで。
前提
バージョン | |
---|---|
Ruby | 2.1.1 |
Rails | 4.2.0 |
下記のテーブルをもとに説明
stores ( 店舗情報 )
列名 | データ型 | 概要 |
---|---|---|
name | string | 店舗名 |
facilities | string | 設備 ※ ここへカンマ区切りで値を格納 |
1. モデルクラスのアクセサメソッドをオーバーライド
セッターで配列をカンマ区切り形式のテキストへ変換。
ゲッターでカンマ区切り形式のテキストを配列へ変換。
app/models/store.rb
def facilities=(value)
str = ''
value.each do |val|
str += val.to_s + ','
end
rslt = str.empty? ? nil : (',' + str)
write_attribute(:facilities, rslt)
end
def facilities
read_attribute(:facilities).to_s.split(';')
end
2. フォームの修正 (複数チェックボックス)
app/views/stores/_form.html.erb
<div class="field">
<%= f.label :facilities %><br>
<%
# デフォルトでチェックをつける項目
checked = @store.facilities.presence || []
# 設備 ( 実際には定数 or DB格納すべきだが ... )
facilities = [1 => "駐車場あり", 2 => "個室あり", 3 => "クレジットカード可"]
# 設備の項目数ぶんループ
facilities.each do |key, value|
checkedval = checked.include?(key) ? true : false
concat f.check_box :facilities, { multiple: true, checked: checkedval }, key, nil
concat value
concat " "
end
%>
</div>
3. コントローラの Strong Parameters 修正
facilities は配列を許可する。
app/controllers/stores_controller.rb
def store_params
params.require(:store).permit(:name, :address, :access, { :facilities => [] })
end
以上。