既存のusersテーブルにenumを導入しようとしたら色々課題があったので記事にしました。
ユーザーの性別や年齢層をセレクトボックスで入力できる仕様にしたい。
-
devise
によりログイン機能が実装されている - 以下のusersテーブル
カラム名 | データ型 | 備考 |
---|---|---|
string | deviseにより導入済み | |
password | string | deviseにより導入済み |
nickname | string | deviseに追加した |
gender | integer | deviseに追加した |
age | integer | deviseに追加した |
enum の設定
Userモデルにenumの定義をしていく。
models/user
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:rememberable, :validatable
with_options presence: true do
validates :nickname
validates :gender
validates :age
end
#~~以下を追加~~
enum gender: {
man: 0,
woman:1,
}
enum age: {
teens: 0,
twenties:1,
thirties:2,
forties:3,
fifties:4,
sixties:5,
seventies:6,
eighties:7,
nineties:8
}
#~~以上を追加~~
end
schema
ActiveRecord::Schema.define(version: 2022_07_17_114402) do
enable_extension "plpgsql"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "nickname", null: false
t.integer "gender", null: false
t.integer "age", null: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
まずはgender
age
にデフォルト値を設定する
正直デフォルト値については現時点(2022/07/18)で理解はできていないがおそらくデータベースに余計なデータが入らない様にする設定だと思われる。nilやnullはデータベースでは特別な扱いらしいので不要なトラブルを避けるためにも設定をしておく。
設定するためには直接マグレーションファイルに書き込むのではなく新規マイグレーションファイルを作成してから反映させなければならない。
既存のテーブルにオプションを追加するために新規マイグレーションファイルを作成
ターミナル
rails g migration setting_is_gender_age_default_on_users
今回はuserテーブルのgender
,age
カラムのデフォルト値をセッティンするので、マイグレーションファイル名はAdd_Is_Gender_Age_Default_On_Users
とします。
作成されたマイグレーションファイルにデフォルト値を追加していきます
新規マイグレーションファイル
class AddIsGenderAgeDefaultOnUsers < ActiveRecord::Migration[6.1]
def change
change_column_default :users, :gender, from: nil, to: 0
change_column_default :users, :age, from: nil, to: 0
end
end
マイグレーションファイルに修正を加えたらデータベースへ反映
ターミナル
rails db:migrate
キチンと反映されているのかschemaファイルとrails dbで確認してみる
schema.rb
ActiveRecord::Schema.define(version: 2022_07_19_030658) do
enable_extension "plpgsql"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "nickname", null: false
t.integer "gender", default: 0, null: false #←default: 0,が追加されている
t.integer "age", default: 0, null: false #←default: 0,が追加されている
t.index ["email"], name: "index_users_on_email", unique: true
end
end
ターミナル
rails db
↓入力待ちになったら以下を入力
\d users
Column | Type | Collation | Nullable | Default
---------------------+--------------------------------+-----------+----------+-----------------------------------
id | bigint | | not null | nextval('users_id_seq'::regclass)
email | character varying | | not null | ''::character varying
encrypted_password | character varying | | not null | ''::character varying
remember_created_at | timestamp without time zone | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
nickname | character varying | | not null |
gender | integer | | not null | 0 ←追加されてる!
age | integer | | not null | 0 ←追加されてる!
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"index_users_on_email" UNIQUE, btree (email)
動作確認
セレクトボックス
一覧表示ページの作成
一旦ここで中断