順序をOrdersテーブルで管理してみた

概要

個人で学習記録を付けるためのアプリを作成しております。

GitHub - nakajima97/laravel-study-record-app-v2: 学習記録アプリのv2
学習記録アプリのv2. Contribute to nakajima97/laravel-study-record-app-v2 development by creating an account on GitHub.

このアプリ内で並び順序を保持するためのテーブルを作成して並び順を保存する実装を行いました。
こちらの実装方法をまとめたページです。

テーブル設計

関係ないテーブルも含まれておりますが、テーブル設計は以下の通りです。
今回の並べ替えに直接関係あるのは以下2つです。

  • categories
  • category_orders

category_ordersのcategory_ordersカラムはcategoriesのidを配列で持つjson型のカラムです。

この方法にした理由

最初に思い浮かんだのがordersカラムを追加してそこで並び順序を保持する方法でした。
これ以外に実装方法ないか探していたところこの方法を採用しているブログがいくつか見つかったので自分もやってみようと思った次第です。

データの取得方法

コードは以下の通り。

public function __invoke($user_id)
{
    $category_order = CategoryOrder::where('user_id', $user_id)->first();
    $query = Category::where('user_id', $user_id)->where('is_archive', false);
    if (!is_null($category_order)) {
        $order = implode(',', $category_order->category_order);
        $query = $query->orderByRaw("FIELD(id, $order)");
    }
    return $query->get();
}

データを取得する際にOrder Byで並び替えを行うのですが
その際にFIELD関数を使って並び替え順を直接指定します。

FIELD関数は以下に説明が書いてあります。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 12.8 文字列関数および演算子

orderByRawは文字列をORDER BYに渡したいときに使えるメソッドです。

10.x データベース:クエリビルダ Laravel

データの保存方法

保存するときにはcategoriesだけではなくcategory_ordersテーブルも更新します。
ここでは末尾に追加するようにしました。

// カテゴリーの並び順を更新
$category_order = CategoryOrder::where('user_id', $user_id)->first();
if (is_null($category_order)) {
    $category_order = new CategoryOrder([
        'user_id' => $user_id,
        'category_order' => [$category->id]
    ]);
} else {
    $category_order->category_order = array_merge($category_order->category_order, [$category->id]);
}
$category_order_save_result = $category_order->save();

感想

ordersカラムを追加してそこで順序を制御する方法は実装したことあったのですが、
今回のようにordersテーブルを作成して順序を制御する方法は初めて実装しました。

並び替えの対象が多すぎない場合はこの方法もありだなと実装して思いました。
並び順を更新するときの対象テーブルが1個しかないのが楽なので。

Follow me!

コメント

PAGE TOP
タイトルとURLをコピーしました