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: true
↓
enum seat: { table: 0, counter: 1}
この記述をすると、下記のようなエラーが出ました
この記述はネットでもよく見かけましたが、
私の場合はenum seat: [:table, :counter], _prefix: trueで上手くいきました。
ご覧いただきありがとうございます。これはアウトプット用のnoteです。
よろしければアドバイスやコメント等お願いします!