7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】enumとは?userに管理権限の例で解説

Last updated at Posted at 2022-01-21

enumとは

integer型string型の1つであり、「enum型」に該当する。
enumとは、1つのカラムに指定した複数個の定数を保存できる様にする為のものである。
文字列と値を関係づけてプログラムの可読性を上げるとともに、データベースに格納される値が規定の範囲を超えることがないようにすることができる。

例えば、0が「応答待ち」、1が「リクエスト中」、2が「処理中」、3が「入力待ち」と設定して、 状態を保持する変数statusがあったとする。

これをプログラム上で数値だけを扱っていると、「どの数値が何を表しているのか」が分からなくなってくる。そのため、定数定義するなどして、数値に名前を付けて可読性を上げるのために使われる。

「enum型」ではその定義の中で名前を羅列すると、それらの名前に自動で値を割り当ててくれる。

大まかな特徴は以下の3つ。
・名前(文字列)のリストに一意の値が割り当てられる

・定義の順番通りに値が割り当てられ、追加や削除すると自動的に割り当て直される(値を指定することも可能)

・enum型の変数は、定義されている以外の値を受け付けない(例外が発生する)

enumの使い方

``Railsのenum```は、モデルに定義することができる型で、定義することで、データベースの特定のカラムの値(整数値)を、指定した文字列(シンボル)で扱うことができる。

まずenumを使うために

1.テーブルにenum用のカラムを用意する
2.モデルにenumの定義をする必要がある。

userに管理権限の有無を例に、
roleカラムにて、0であれば一般ユーザー・1であれば管理者ユーザーとして権限を与える例でやっていく。

1.テーブルにenum用のカラムを用意する

まずはuserテーブルroleカラムを追加する際には型を、Integer型boolean型の2択になる。

◆integer型
2個以上の定数を紐付けたい場合は型はinteger型で定義。

◆boolean型
2個の定数を紐付けたい場合かつ真偽値を保存したい時はboolean型で定義。
enumを設定しなくてもboolean型だけで充分機能は実装できるのでenumを設定する必要は特にないので、基本的にはinteger型で良さそう)

今回はinteger型での実装例として扱う。

add_role_to_users.rb
class AddRoleToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :role, :integer, default: 0, null: false
  end
end

空白データは存在しない前提なので、null: falseにしdefault: 0(初期値には0)を指定する。

2.モデルにenumの定義

user.rb
class User < ApplicationRecord
  #hashで定義する場合
  enum role: { general: 0, admin: 1 }

  # シンボル配列で定義する場合
  enum role: [ :general, :admin]

  # 文字配列で定義する場合
  enum role: [ "general", "admin"]

end

基本的にどの方法で定義しても可能。特に大きな違いはないが、しいて挙げるならば下記の2つが違いになる。

・hashの定数と整数の紐付けは0から始めなくても良い
・配列で定義する方がインデックスが自動で定数と紐づいてくれるので、記述量が少なくすっきりしたコードになる

◆enumを定義する上での注意点
enumのカラムを設定するときに気をつけないといけないことは、カラムに予約語を設定すること。

予約語とは、言語側(今回で言うとruby)で既にこの単語は言語(ruby)で使用しているから使わないで、という単語のこと。
例えばrubyではnilとは何もないという意味がある。これを変数で定義すると

nilを変数として定義した場合.
nil = '何もない'
SyntaxError: (irb):1: Can't assign to nil

上記の様に、nilは既にruby側で定義しているので変数として定義できないというエラーが出る。
これはつまり、ruby側nilという単語は何もないという意味で既に予約している(定義している)ので、変数としては使わないで、ということになる。この様に言語側で既に使うと予約してる単語を予約語と言う。

enumは複数の定数を登録するので、カラム名をActiveRecordで使用している予約語のtypeにしてしまいがちなので、予約語はカラム名として使えないためエラーになるので注意。

enumの便利なメソッド

・確認メソッド
今enumカラムに入っている定数が何なのか確認するメソッドのこと。

確認メソッド.
#あるuserが管理権限を持っているかどうか確認するとき
user.general?
=> false

user.admin?
=> true

user.test?
NoMethodError: undefined method `test?'

確認メソッドは上記の様に使用する。

モデルのインスタンスに対してインスタンス.定数名?の形でenumカラムに指定した定数が入っていればtrueが返ってきて、指定した定数が入っていなければfalseが返ってくる。

そして登録していない定数であるuser.test?に関しては、エラーが出る。

・更新メソッド
更新メソッドとは、enumカラムに入ってある定数を別の定数に更新するメソッドのこと。
モデルのインスタンスに対してインスタンス.定数名!の形で使う。

更新メソッド.
あるuserに管理権限を付与するとき
user.role
=> "general"

user.admin!
UPDATE `users` SET `role` = 1,..省略
=>true

・定数リスト取得メソッド
定数リスト取得メソッドとは、モデルファイルのenumに記載している複数個の定数リストを取得するメソッドのこと。
モデルクラス.enumカラム名の複数形という形で使用。

定数リスト取得メソッド.
User.roles
=> {"general"=>0, "admin"=>1}

enumの日本語対応

Railsには、enumをi18n対応させるgem「enum_help」が用意されているので、簡単に行うことができる。

手順
1.enum_helpのインストール
2.localeファイルの作成

1.enum_helpのインストール
Gemfileにgem 'enum_help'と記載後、bundle installを実施。

2.localeファイルの作成
config/locales/activerecord/ja.ymlファイルを作成し、翻訳を記載。

ja.yml
ja:
  activerecord:
  enums:
   user:
    role:
     general: 一般ユーザー
     admin: 管理者

userに対してrole_i18nインスタンスメソッドを使うと、日本語化出来たかどうか確認ができる。

ターミナル.
irb(main):001:0> User.roles_i18n
=> {"general"=>"一般", "admin"=>"管理者"}

参考記事

【Rails入門説明書】enumについて解説
【Rails】 enumチュートリアル

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?