[未経験エンジニア]のオリジナルアプリ制作の反省4. 「enumを効果的に使う」

# 今回書くこと
enumを用いて、下書き機能を実装する

## 環境
Ruby 2.6.5
Ruby on Rails 6.0.4.3

## 結論
数値を保存して、その数値に紐づく値を操作する。
（これだけだとなんのこっちゃわからないので、もう少し読み進めてみてください）

#ざっくりとした実装の流れ
- enum用のカラムをテーブルにセット
- テーブルに紐づくモデルにenumをセット

という設定を経て、enumという機能を少し深掘りしていきます。

## enum用のカラムをテーブルにセット
enumの実装には、テーブルenum用のカラムをセットしないといけません。

ここでは、既にあるarticlesテーブルにカラムをセットする形で説明を続けます。

ターミナルで

```terminal
rails g migration AddStatusToArticles status:integer
```
と実行すると、マイグレーションファイルが作成されるので

```----------_add_status_to_articles.rb
class AddStatusToArticles < ActiveRecord::Migration[6.0]
  def change
    add_column :articles, :status, :integer, null: false, default: 0
  end
end
```

オプションとしてnull: false, default: 0を付与して
ターミナルで、必殺！

```
rails db:migrate
```

これで、テーブルにenum用のカラムが追加されました。

##テーブルに紐づくモデルにenumをセット
次に、今カラムを追加したテーブルに紐づいているモデルに記述を行っていきます。とは言っても、とてもシンプルな記述です。
今回は、articlesテーブルに紐づくarticleモデルに記述していきます。

```article.rb
class Article < ApplicationRecord
  enum status: { draft: 0, published: 1 )

  (略)
end
```

少し説明を加えます。
まず、enum用に作ったカラムを指定します。

```
  enum status:
```
そこに、シンボルを用いて

```
{ draft: 0, published: 1 )
```
と記述します。意味は「**draftは0、publishedは1という数字でDBに保存されるよ**」となります。

言い換えると、**DBには0が保存され、draftはソースコード上で用いる値となる**、というふうに理解するといいと思います。publishと1の関係も同様です。

これで、enumを使って下書き機能を実装する準備が整いました。

## なぜenumを使う必要があるのか？
ここまで、enumの使い方についてお話ししてきました。
では、なぜenumを用いる必要があったのでしょうか？

先に、Pikawakaの[【Rails】enumチュートリアル]（https://pikawaka.com/rails/enum）の記事から、説明を引用させていただくと

>１つのカラムに指定した複数個の定数を保存できる様にする為のモノです。

とあります。僕なりに噛み砕いてみると
**「なんらかの状態を示すあらかじめ決まった複数のデータを、カラムに数字で保存し、その数字に紐づく値を利用するための機能」**
と言い換える事ができると思います。

先ほど見ていただいたdraftとpublishedは、「下書き・公開」という**状態**をそれぞれ持っています。
通常カラムには文字列や数値などだけを保存していますが、enumを用いると、**「数値と値」**という組み合わせでカラムに保存する事が可能になります。この値を操作する事で、実際に様々な機能を実装する事ができます。これが、enumを利用する理由です。

## 実際の活用例
さて、ここまではenumの設定の仕方、enumを利用する理由についてお話ししてきました。　
ここからは、[こちらの記事](https://pikawaka.com/rails/enum#enum%E3%81%AE%E4%BE%BF%E5%88%A9%E3%81%AA%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)を参考に、enumを設定すると使えるメソッドを利用した例を少し紹介します。

まずは、「一覧表示には、公開済みの記事のみを表示する」(検索メソッド)

```articles_controller.rb
def index
  @articles = Article.published.order(created_at: :desc).includes(:user)
end
```
このように、モデル.pubslished(draft)とすると
**articlesテーブルのstatusカラムの値が1のもの (=publisehd)だけ**をSQLで呼び出してくれます。

ビューへの表示は本筋から外れますので、ここでは省略します。（eachメソッドを使うなどして表示する事ができると思います。）

次に、「更新された記事が公開済みかどうかで条件分岐させる」（確認メソッド）

```articles_controller.rb

def update
 @form = ArticleTag.new(article_params, article: @article)
 if @form.save
   if @article.published?
  　 redirect_to article_path(@article), notice: '投稿の更新が完了しました！'
   else
　　 redirect_to root_path, notice: '記事を下書きに戻しました。'
   end
（略）
end
```

4行目に注目してください。@articleは編集された情報の中で、記事の情報を示しています。ここに".published?"とする事でその記事が更新されたかどうかでその後の処理を変えています。

僕は、主にこの二つの用途で利用しましたが、他にも便利なメソッドがあるみたいです。詳しく知りたいという方は、上でもあげた、[こちらの記事](https://pikawaka.com/rails/enum#enum%E3%81%AE%E4%BE%BF%E5%88%A9%E3%81%AA%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)をご覧ください。

## オマケ
僕の記事では何度も紹介している、[Pikawaka](https://pikawaka.com/)というサイトは、初心者にもわかりやすく（わかりやすすぎるくらいに）、Ruby, Ruby on Rails, JavaScriptを中心に、丁寧に説明してくれています。検索機能もついていますので、困ったら一度利用してみることをオススメします。

## 最後に
最後まで読んでいただいた皆様、ありがとうございます。
ソースコード、記事の書き方について**「もっとこうしたほうがいいよ！」というご意見**、**「そこどうなっているの？」というご質問**など、お待ちしております。

## 参考文献

- [カラムを追加・削除・編集する方法 ❏Rails❏](https://qiita.com/ITmanbow/items/2bf4dfa4d9ca705b97df)
- [[Rails]enumチュートリアル](https://pikawaka.com/rails/enum#enum%E3%81%AE%E4%BE%BF%E5%88%A9%E3%81%AA%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)
- [Pikawaka](https://pikawaka.com/)←オススメ！