はじめに
子テーブルにあるS,A,Bのようなランクでソートをかける時に苦戦をしたので、その方法を解説します。
以下のテーブルがある前提で、このテーブルのソートについて解説していきます。
usersとuser_detailsは1対1の関係です
users |
---|
id |
name |
user_details |
---|
id |
user_id |
rank |
ランクでソートする方法
ランクでソートをするにはLaravelのorderbyRawを使用します。
ランクはS,A,Bという値があり、昇順でソートする場合は以下のようになります。
UserDetail::orderByRaw("CASE rank
WHEN 'S' THEN 1 WHEN 'A' THEN 2 WHEN 'B' THEN 3 END ASC");
")->get()
子テーブル+ランクでソートする方法
以下のようにselectで子テーブルの項目を抽出してから、その値でソートをかければできます。(selectを使用すれば、リレーションの使用ができます)
User::select('users.*', DB::raw('(SELECT rank FROM user_details WHERE users.id = user_details.appointment_id ) as sort_rank'))
->orderByRaw("CASE sort_rank
WHEN 'S' THEN 1 WHEN 'A' THEN 2 WHEN 'B' THEN 3 END ASC");
")->get()
終わりに
今回、子テーブルのソートの時にjoin()を使用してもよかったのですが、リレーションが使用できなくなってしまうため、selectを使用しました。
また、with()も使用する方法が考えられましたが、with()は最後にget()を呼び出した時にリレーション先のテーブルを結合するので、クエリビルダーのみで書くことができず、get()の後にコレクションメソッドを駆使しながらソートする羽目になりそうなので使用しませんでした。
他にいい方法などありましたら教えていただけると幸いです。