見出し画像

enumを使い、複数の項目を一つのカラムに保存する




[はじめに]

○飲食店のホームページを制作しています。
○予約システムを実装したかったため、
「enum」と「radio_button (form_with)」を使って
 "テーブル席"か"カウンター席"を選んでもらう項目を作成しました。



[実装手順]

①予約システム用のモデル、テーブル、コントローラーを作成する
今回はモデル名をformとし、seatカラムにenumを使っていきます。

<マイグレーション>

class CreateForms < ActiveRecord::Migration[6.0]
  def change
    create_table :forms do |t|
      t.string   :last_name_kana,      null: false
      t.string   :first_name_kana,     null: false
      t.string   :phone_number,        null: false
      t.string   :number_of_people,    null: false
      t.integer  :seat,                null: false, default: 0  ⬅️
      t.datetime :datetime,            null: false

      t.timestamps
    end
  end
end

(ポイント)
DBにはseatの各項目を、数値で保存したいので
・型はinteger
・default: 0 を記述します

<モデル>

class Form < ApplicationRecord
  enum seat: [:table, :counter], _prefix: true    ⬅️

  with_options presence: true do
    validates :last_name_kana, format: { with: /\A[ァ-ヶー-]+\z/, message: 'is invalid. Input full-width characters.'}
    validates :first_name_kana, format: { with: /\A[ァ-ヶー-]+\z/, message: 'is invalid. Input full-width characters.'}
    validates :number_of_people, numericality: { only_integer: true, message: 'is invalid. Input only number'}
    validates :datetime
  end

  VALID_PHONE_REGEX = /\A\d{10}$|^\d{11}\z/
validates :phone_number, presence: true, format: { with: VALID_PHONE_REGEX }
validates :phone_number, numericality: { only_integer: true, message: 'is invalid. Input only number' }
    
end

⚠️私の場合
[:table, :counter] を {:table, :counter} にすると
syntaxエラーが起きました。
よかったら気をつけて見てみてください。

<コントローラー>

class FormsController < ApplicationController
  
  def index
    @form = Form.new
  end

  def create
    @form = Form.new(form_params)
    if @form.save
      render :create
    else
      render :index
    end
  end

  private 
  
  def form_params
    params.require(:form).permit(:last_name_kana, :first_name_kana, :phone_number, :number_of_people, :datetime, :seat)
  end
end


<ルーティング>

Rails.application.routes.draw do
  root to: "tops#index"

  resources :tops
  resources :forms, only: [:index, :create]    ⬅️
end



②enumを日本語対応させる

②-1
gemをインストール

🗂→Gemfile


#一番下に
gem "enum_help"

bundle install

②-2
config/locales の下に ja.ymlファイルを作成、記述

🗂→config/locales/ja.yml

ja:     #日本語
  enums:     #複数形にする
     form:     #モデル名
       seat:     #カラム名
         table: テーブル席     #各項目名
         counter: カウンター席    



[表示]

今回はform_withのradio_buttonを使って表示します

<div class="form-group">
      <div class='form-text-wrap'>
        <label class="form-text">席指定</label>
        <span class="indispensable">*必須</span>
      </div>
      <div class='input-wrap'>
        <div>
        <%= f.radio_button :seat, :table, checked: true %>
        <%= f.label :seat, "テーブル席", {value: :table, style: "display: inline-block;"} %>      ⬅️
        </div>
        <div>
        <%= f.radio_button :seat, :counter %>
        <%= f.label :seat, "カウンター席", {value: :counter, style: "display: inline-block;"} %>            ⬅️
        </div>
      </div>
    </div>

(ポイント)
1.
ラジオボタンと、テキストは
「f.radio_button」 、「f.label」 と分けて記述します。

このように表示できます

2.
<%= f.radio_button :seat, :table, checked: true %>  の
「checked: true」は、このページを開いた瞬間から
項目が選択されている状態に設定できるオプションです。




これで完了です🤲



[保存した結果]

テーブル席 = 0
カウンター席 = 1
として、sequelproでDBを確認すると

数値で保存されます



[注意]


<モデル>

enum seat: [:table, :counter], _prefix: trueenum seat: { table: 0, counter: 1}

この記述をすると、下記のようなエラーが出ました

この記述はネットでもよく見かけましたが、
私の場合はenum seat: [:table, :counter], _prefix: trueで上手くいきました。







ご覧いただきありがとうございます。これはアウトプット用のnoteです。
よろしければアドバイスやコメント等お願いします!

いいなと思ったら応援しよう!