[Rails]enumを使ってユーザに性別を追加する1/2
はじめに
作成したRailsアプリに、ユーザのテーブルに性別カラムgender
を追加します。
ユーザー登録時の性別のセレクト部分はenumを使って「その他・男性・女性」が表示され、その際に特に操作が無かれば「その他」が選択されるようにしていきます。
環境
Rails 6.1.4.1
ruby 3.0.2
tl;dr
- enumとは
- ユーザテーブルにgenderカラムを追加する
- enumを宣言する
-
enum_help
gemを使う - genderをローカライズする
- ユーザコントローラーを編集する
- ビューにセレクトボックスを追加する
enumとは
enum
は、Railsで提供される機能の一つです。enum
を使用すると、データベースの列(カラム)に対して、あらかじめ定義された値のセットを関連付けることができます。
具体的には、enum
を使用してモデルの属性を定義すると、その属性の値をシンボルで指定できるようになります。これにより、データベース内で整数値として保存される属性に、より意味のある値を関連付けることができます。
以下は、enum
の使用例です:
class User < ApplicationRecord
enum role: [:admin, :user, :guest]
end
上記の例では、User
モデルにrole
属性を定義しています。enum
メソッドを使ってrole
属性を定義し、:admin
、:user
、:guest
の3つの値を定義しています。
これにより、User
モデルのインスタンスに対して以下のようにアクセスできます:
user = User.new(role: :admin)
user.admin? # true
user.role # "admin"
また、enum
はデフォルトでいくつかの便利なメソッドも提供しています。たとえば、各値に対応する真偽値のメソッド(admin?
、user?
、guest?
)や、定義された値の一覧を返すメソッド(User.roles
)などです。
enum
はデータベースの列に関連付けるだけでなく、モデルのビューなどの表示部分でも利用できます。たとえば、フォームのセレクトボックスに値を表示する際には、User.roles.keys
を使って選択肢を取得することができます。
enum
を使うことで、整数値だけでなく、意味のある値を使って属性を扱うことができ、コードの可読性と保守性が向上します。
ユーザテーブルにgenderカラムを追加する
bin/rails generate migration AddGenderToUsers
Running via Spring preloader in process 47375
invoke active_record
create db/migrate/20230624074517_add_gender_to_users.rb
class AddGenderToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :gender, :interger, default: 0
end
end
bin/rails db:migrate
Running via Spring preloader in process 48507
== 20230624074517 AddGenderToUsers: migrating =================================
-- add_column(:users, :gender, :interger, {:default=>0})
-> 0.0031s
== 20230624074517 AddGenderToUsers: migrated (0.0032s) ========================
ユーザのgenderがデフォルトになっていることを確認します。
irb(main):005:0> User.first.gender
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> 0
enumを宣言する
class User < ApplicationRecord
enum gender: {other: 0 , male: 1, female: 2}
end
enum_help
gemを使う
enum_help
とはenum
で定義した値をi18n
化させることができるgemです。
gem 'enum_help'
bundle install
genderをローカライズする
ja:
enums:
user:
gender:
other: その他
male: 男性
female: 女性
これでenum_help
によるメソッドが使えるようになりました。
翻訳されたことを確認します。
irb(main):001:0> user = User.first
(0.9ms) SELECT sqlite_version(*)
User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=>
#<User:0x00007fe2e351e820
...
irb(main):002:0> user.gender
=> "other"
irb(main):003:0> user.gender_i18n
=> "その他"
irb(main):005:0> User.genders
=> {"other"=>0, "male"=>1, "female"=>2}
irb(main):006:0> User.genders_i18n
=> {"other"=>"その他", "male"=>"男性", "female"=>"女性"}
irb(main):007:0> User.genders_i18n.invert
=> {"その他"=>"other", "男性"=>"male", "女性"=>"female"}
irb(main):08:0> User.genders_i18n.invert.map{|key,value|[key,value]}
=> [["その他", "other"], ["男性", "male"], ["女性", "female"]]
irb(main):09:0> User.genders_i18n.invert.map{|key,value|[key,User.
genders[value]]}
=> [["その他", 0], ["男性", 1], ["女性", 2]]
ユーザコントローラーを編集する
パラメーターにgender
を追加します。
性別セレクト用オプションを作成します。
class UsersController < ApplicationController
def new
@user = User.new
@gender_options = User.genders_i18n.invert.map{|key,value|[key,value]}
end
private
def user_params
params.require(:user).permit(:email, :name, :gender, :password, :password_confirmation)
end
end
app/views/users/new.html.erb
を編集する
ユーザーの新規作成フォームに性別のセレクトを追加していきます。
<div class="mb-3">
<%= f.label :gender %>
<%= f.select :gender, @gender_options, { include_blank: '性別を選択してください' }, class: 'form-control' %>
</div>
ユーザを作成し、選択した性別をDBに登録されたことを確認します。
また、何も選択しない場合ではDBに0(その他)を登録されたことを確認します。
終わりに
gemを使わないで実装する方法もあるみたいので、今度そちらも試していきたいと思います。
Discussion