Rails - enumの使い方

##はじめに

プログラミングスクールでチーム開発を行った際に、初めて__enum__を使いました。

忘れないようアウトプットしていこうと思います。


誤りがあれば、ご指摘いただけると幸いです。
<br>
##enumとは

日本語訳は、「__列挙型__」
列挙：一つ一つ数え立てて挙げること。並べ立てること。


`integer型のカラムに対して、
数値ごとに対応する任意の名前をつけることができます。`

<br>
ーーーーーーーーーーーーーーーーーーーー
Ex）
ECサイトで支払い方法を保存するカラム
カラム名：`payment`
データ型：`integer`

数値 __1__のとき : `クレジットカード` という名前として扱う
数値 __2__のとき : `銀行振り込み` という名前として扱う
数値 __3__のとき : `代引き` という名前として扱う

このように、
保存されている数値に応じて、名前を自由に変えることができます。

ーーーーーーーーーーーーーーーーーーーー
<br>
##使い道

基本的には、カラムで用いる値が複数個に固定されているときがおすすめです。

ーーーーーーーーーーーーーーーーーーーー
Ex)
有効 or 無効
○ or △ or ×
販売中 or 売切れ中 or 残りわずか
クレジットカード or 銀行振り込み or 代引き
ーーーーーーーーーーーーーーーーーーーー

色々な記事を見ましたが、
頻繁に更新が発生したり、複数モデルで利用する場合は
修正が大変になる可能性がある為、好ましくないようです。

##書き方

####１ ： integer型のカラムを定義します。

```ターミナル.
rails g migrate create_orders
```
マイグレーションファイルを作成します。
<br>

```ruby:20210316134657_create_orders.rb
class CreateOrders < ActiveRecord::Migration[5.2]
  def change
    create_table :orders do |t|
      t.timestamps
      t.integer :member_id
      t.integer :postage, null: false
      t.string :postal_code, null: false
      t.string :address, null: false
      t.string :name, null: false
      t.integer :payment, null: false, default:0
      t.integer :total_price, null: false
      t.integer :order_status, null: false, default:0
    end
  end
end

```
<br>必要なカラムを定義します。
ここでは、`order_status`に__enum__を使おうと思い、integer型で定義しています。
<br>

```ターミナル.
rails db:migrate
```

マイグレーションファイルの反映もお忘れなく。
<br>
####2 ： enumを定義します

enumの定義は__モデル__内で行います。

```ruby:order.rb
enum order_status: {
  入金待ち: 0,
  入金確認: 1,
  製作中: 2,
  発送準備中: 3,
  発送済み: 4}
}
```

対応するモデルに
`enum カラム名: {名前1: 数値1, 名前2:　数値2 }`のように書けば定義完了。


これで、`order_status`に0~4の値が入った時、
その値ごとに命名した名前を使うことができます。


##使用事例

`rails c`を使って見てみましょう。

事前に登録しておいて注文( id : 1 )を見てみましょう！

```ruby:ターミナル.
2.6.3 :001 > order = Order.find(1)
  Order Load (0.2ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 => #<Order id: 1, created_at: "2021-03-28 03:05:09", updated_at: "2021-03-28 03:05:09", member_id: 1, postage: 800, postal_code: "1974905", address: "東京都品川区上大崎2-15-22", name: "てすと太郎", payment: "0", total_price: 3660, order_status: "入金待ち"> 
```

長い出力結果になってしまい、見づらいかもしれませんが、
出力結果の１番最後に`order_status:"入金待ち"`となっているのがわかると思います。

これは、
__order_statusの初期値が0 (default : 0)__
__0の時、"入金待ち"となるようenumで定義 (入金待ち : 0)__
この２つが作用しての結果になっています。
<br>

では、このorderのorder_statusを更新してみましょう。

先ほどOrder.find(1)は変数orderに代入しています。
そのままorderを使ってupdateしてみます。

```ruby:ターミナル.
2.6.3 :002 > order.update(order_status: 1)
   (0.3ms)  begin transaction
  Member Load (0.1ms)  SELECT  "members".* FROM "members" WHERE "members"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Order Update (4.2ms)  UPDATE "orders" SET "updated_at" = ?, "order_status" = ? WHERE "orders"."id" = ?  [["updated_at", "2021-03-28 03:13:44.190705"], ["order_status", 1], ["id", 1]]
   (4.5ms)  commit transaction
 => true 


2.6.3 :003 > order
 => #<Order id: 1, created_at: "2021-03-28 03:05:09", updated_at: "2021-03-28 03:13:44", member_id: 1, postage: 800, postal_code: "1974905", address: "東京都品川区上大崎2-15-22", name: "てすと太郎", payment: "0", total_price: 3660, order_status: "入金確認"> 
```

こちらも長くて見づらいですが、
出力結果の１番最後に`order_status:"入金確認"`と値が更新されているのがわかります。

__order_statusを 1 に更新したことで、__
__enumを参照し、命名した名前に値を更新できました。__
<br>

##さいごに

今回書いたenumの使い方は、基本中の基本になります。

チーム開発では、
・if文内での条件分岐enumを使う
・form_with内のselectでenumを使う
・enumを使ったカラムの変更を参照して他enumの値を連動して変更する
など様々な機能を実装しました。

まだまだ未熟者ですが、
少しでも誰かの参考になれば幸いです。

<br>
##もっと詳しく知りたい方はこちら

私がenum初めましての時にとても参考にさせていただきました。
私もこれらのようにわかりやすく、詳しく書けるようになりたい。

[【Rails】Enumってどんな子？使えるの？](https://qiita.com/ozackiee/items/17b91e26fad58e147f2e#enum%E3%81%A8each%E6%96%87%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%8B)

[【Rails】 enumとは? enumを用いてselectボックスを作ってみた](https://qiita.com/clbcl226/items/3e832603060282ddb4fd)