【Rails】チェックボックスで✅した内容を”配列から出して”保存する方法


自己紹介

初めまして!2021年5月からプログラミングの勉強を始めた、THEプログラミング初心者です。

今回初めて記事を書かせて頂きます。
主に自分用の備忘になりますが、
もし同じ悩みを持つプログラミング初心者の方がいれば、少しでも力になれたら嬉しいです。
また、何か間違い等ありましたらご指摘頂けますと幸いです。

はじめに

サイトを参考に、アレルギー表示のためのチェックボックスを実装しました。
※「複数のチェックボックスを作成する方法」の前半を基に作成しました。


チェックボックスにチェックをするまでは良いのですが、
そのチェックしたテキストを表示する際に、配列[ ]に入ったまま表示されてしまいました。

(そもそも↑記事では配列に入れるよう指定していると後に分かるのですが…)
どうしても配列から出して、文字列だけで表示したい!と思い、少し手を加えたものを備忘として残します。

開発環境

ruby 2.6.3
rails 5.2.5

チェックボックス作成

今回、ECサイトの管理者が、商品追加投稿欄でアレルギー表示をチェックします。
商品に関わるコントローラーをitems_controller.rbとしています。

(1)item.rb (itemモデル) にアレルギーカラムを追加

itemsテーブルにallergiesカラム追加
class AddColumnItems < ActiveRecord::Migration[5.2]
  def change
    add_column :items, :allergies, :text
  end
end

(2)投稿画面を作る ※一部省略

new.html.erb
<%= form_with model: [:admin, @item], local:true do |f| %>
  <table>

〜省略〜

  <tr>
   <th>アレルギー表示</th>
    <td colspan="2">
      <% %w(卵 牛乳 小麦 大豆 なし).each.with_index do |allergy,i| %>
        <label>
        <%= check_box_tag 'item[allergies][]', allergy, false, id: "item_allergies_#{i}" %>
        <%= allergy %>
         </label>
      <% end %>
    </td>
  <tr>

〜省略〜

  </table>

<& end %>

(3)コントローラー記述 ※一部省略

items_controller.rb
class Admin::ItemsController < ApplicationController
  before_action :authenticate_admin!
  # ↓これが必要
  before_action :allergy_string, only: [:create, :update]

  def new
    @item = Item.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to admin_item_path(@item.id)
    else
      render 'new'
    end
  end

  def show
    @item = Item.find(params[:id])
  end

  def update
    @item = Item.find(params[:id])
    if @item.update(item_params)
      redirect_to admin_item_path(@item.id)
    else
      render 'edit'
    end
  end

  private
  # もしアレルギー表示が一つでもチェックされたら、配列内の文字列をjoin(結合)し半角スペースを開ける
  def allergy_string
    if params[:item][:allergies].present?
      params[:item][:allergies] = params[:item][:allergies].join(" ")
    end
  end

  def item_params
    params.require(:item).permit(:image, :name, :information, :genre_id, :price, :is_active, :allergies)
  end

end



(4)完成

これで無事に配列から解放されました!笑

ちなみに…

参考サイトでは、配列に入れるよう指定されていました。

def item_params
 params.require(:item).permit(:image, :name, :information, :genre_id, :price, :is_active, allergies:[])
end

どうやら、allergies:[ ]が配列に文字を入れるという意味の一つだと思われます。(viewの表記にも配列に入れるっぽいのがあるが)
だからといってallergy_stringの定義なしに、:allergiesにすると今度は値自体が保存されないので、
上記のようにするのが、現時点ではベストだと判断しました。

終わりに

今回は以上です。
この方法だとテキスト(卵 牛乳とか)自体は保存され、”アレルギー表示は卵と牛乳と小麦”と表示されますが、”チェックを入れた状態”は保存されない"ので注意が必要です。

冒頭にも述べましたが、ご指摘やアドバイスがありましたらコメントして頂けますと幸いです。