開発をはじめて半年の私がデータの並び替えで使えるなぁと思ったもの

開発業務に携わって半年、
データの並び替えで使えるなぁと思ったものを2つ書き留めておきます。

開発環境
・Ruby
・Rails
・MySQL
・Mac

なお、この記事で「order」とは、「取得したレコードを特定のキーで並び替える」ことを指します。
[参考] https://railsdoc.com/page/model_order

#### 今回使うテーブル
Naoさん、Kenさん、Mikaさんのやることリストテーブルを仮定します。
contentはやることリストの内容、personは人、categoryは項目のカテゴリー、dateは日付を格納する想定です。

```
+----+------------+--------+--------------+------------+
| id | content    | person | category 　　　　　　　　| date       | 
+----+------------+--------+--------------+------------+
| 1  | 女子会      | Nao    | friend       | 2022-12-10 |
| 2  | 回覧板　     　| Ken    | high-priority| 2022-12-08 |
| 3  | トレーニング　　　　　| Ken    | gym   　　　　　　　　　　　　　　| 2022-12-10 |
| 4  | zoom飲み会  | Mika   | friend  　　　　　　　　 | 2022-12-15 |
| 5  | なすび　　　　　　　　　　　　　| Nao    | shopping 　　　　　　　　| 2022-12-08 |
| 6  | ぼうし　　      | Mika   | shopping  　　　　 | 2022-12-12 |
| 7  | ユニバ　　　　　　　　　　　　　| Ken    | friend   　　　　　　　　| 2022-12-25 |  
| 8  | トレーニング  　| Ken    | gym          | 2022-12-13 |
| 9  | 飲み会      | Nao    | high-priority| 2022-12-22 |   
| 10 | 飲み会　　     | Mika   | friend  　　　　   | 2023-01-11 |
| 11 | 出張       　| Nao    | high-priority| 2023-01-15 |     
| 12 | トレーニング  　| Ken    | gym          | 2022-12-17 |
| 13 | トレーニング  　| Ken    | gym          | 2022-12-21 |
+----+------------+---------+--------------+-----------+
```

### 1. select句でorder用のカラムを用意して並び替える

やりたいこと：自分(Ken)のやることを日時順で並べ、その後に他の人のやることを日時順で並べる

#### イメージ(自分：Ken)
```
+----+------------+--------+--------------+------------+
| id | content    | person | category 　　　　　　　　| date       | 
+----+------------+--------+--------------+------------+
| 2  | 回覧板　     　| Ken    | high-priority| 2022-12-08 |
| 3  | トレーニング　　　　　| Ken    | gym   　　　　　　　　　　　　　　| 2022-12-10 |
| 8  | トレーニング  　| Ken    | gym          | 2022-12-13 |
| 12 | トレーニング  　| Ken    | gym          | 2022-12-17 |
| 13 | トレーニング  　| Ken    | gym          | 2022-12-21 |
| 7  | ユニバ　　　　　　　　　　　　　| Ken    | friend   　　　　　　　　| 2022-12-25 |
| 5  | なすび　　　　　　　　　　　　　| Nao    | shopping 　　　　　　　　| 2022-12-08 |
| 1  | 女子会      | Nao    | friend       | 2022-12-10 |
| 6  | ぼうし　　      | Mika   | shopping  　　　　 | 2022-12-12 |  
| 4  | zoom飲み会  | Mika   | friend  　　　　　　　　 | 2022-12-15 |
| 9  | 飲み会      | Nao    | high-priority| 2022-12-22 |
| 10 | 飲み会　　     | Mika   | friend  　　　　   | 2023-01-11 |
| 11 | 出張       　| Nao    | high-priority| 2023-01-15 |
+----+------------+---------+--------------+-----------+
```

#### 実装
```ruby
# ログインユーザー
current_user = session[:current_user]

Memo.select(:content, 
            :person, 
            :category, 
            :date, 
            "CASE person WHEN #{current_user} THEN 0 ELSE 1 END person_priority")       
    .order(person_priority, date: :desc)
```

クエリ発行回数も1回で済み、綺麗に書けるのでメンテナンス性の面でも良いのではないでしょうか。


### 2. field関数を用いて並び替える
やりたいこと: カテゴリーの任意の順番(high-priority > friend > shopping > gym)で並べる。
#### イメージ
```
+----+------------+--------+--------------+------------+
| id | content    | person | category 　　　　　　　　| date       | 
+----+------------+--------+--------------+------------+
| 2  | 回覧板　     　| Ken    | high-priority| 2022-12-08 |
| 9  | 飲み会      | Nao    | high-priority| 2022-12-22 |
| 11 | 出張       　| Nao    | high-priority| 2023-01-15 |
| 1  | 女子会      | Nao    | friend       | 2022-12-10 |
| 4  | zoom飲み会  | Mika   | friend  　　　　　　　　 | 2022-12-15 |
| 7  | ユニバ　　　　　　　　　　　　　| Ken    | friend   　　　　　　　　| 2022-12-25 |
| 10 | 飲み会　　     | Mika   | friend  　　　　   | 2023-01-11 |
| 5  | なすび　　　　　　　　　　　　　| Nao    | shopping 　　　　　　　　| 2022-12-08 |
| 6  | ぼうし　　      | Mika   | shopping  　　　　 | 2022-12-12 |
| 3  | トレーニング　　　　　| Ken    | gym   　　　　　　　　　　　　　　| 2022-12-10 |  
| 8  | トレーニング  　| Ken    | gym          | 2022-12-13 |        
| 12 | トレーニング  　| Ken    | gym          | 2022-12-17 |
| 13 | トレーニング  　| Ken    | gym          | 2022-12-21 |
+----+------------+---------+--------------+-----------+
```
#### 実装
```ruby
list = 'high-priority', 'friend', 'shopping', 'gym'

Memo.order("field(:category, list)")
```
こちらもスッキリかけて、並べ替えの意図がかんたんに読み取れるため可読性が高く、メンテナンス性も高いのではないでしょうか。

### 最後に
より綺麗で、メンテナンス性の高いコードを目指して勉強していこうと思います。