【Laravel】EloquentでwhereInを使った場合に配列の並び順にソートする方法

こんにちわ、最近SpotifyにハマっているTakaです。さて、今回はLaravelの備忘録として、EloquentでWhereInを使ってデータ検索した場合に、指定した配列の並び順にソートする方法を紹介したいと思います。

 なお、Laravelとはなんぞやという方は下の記事を参照してください!

 さて、本題に移りますが、例えばEloquentで指定したIDのデータだけをDBから取得したい場合、あらかじめ配列に取得したいデータのIDだけを設定しておいて、whereInを使って実行すれば指定したデータだけ取得できます。その場合のサンプルコードが下記になります。


$ids = array(1,10,5,9,3);
$data = Data::whereIn('id', $ids)->get();


 この場合は、Dataモデルで指定したテーブルからIDが「1,10,5,9,3」のデータを取得します。その場合の取得結果がこの配列の並び順に出てくれればいいのですが、バラバラになって出てくる場合があります。これを配列の並び順に取得するサンプルコードが下記になります。


$ids = array(1,3,5,7,9);
$ids_order = implode(',', $ids);
$data = Data::whereIn('id', $ids)->orderByRaw(DB::raw("FIELD(id, $ids_order)"))->get();


 気づいた人も多いと思いますが、Eloquentとクエリービルダーの合わせ技ですね。少しタイトル詐欺になってしまい、すいません。

 まず、「implode」で配列を文字列に連結して、orderByRawを使ってクエリービルダーで生クエリを使ってあげれば配列の順番通りに取得できます。

 なお、DB:rawメソッドは生クエリになりますので、SQLインジェクションには注意して、必ず事前にエスケープ処理をしてください。

2018.02.06追記

 ちなみに、orderByRawメソッドもSQL文が書けるので、わざわざDB::rawメソッドを使わなくても大丈夫でした。下のコードでもいけます。こちらの方がスッキリしていていいですね。


$ids = array(1,3,5,7,9);
$ids_order = implode(',', $ids);
$data = Data::whereIn('id', $ids)->orderByRaw("FIELD(id, $ids_order)")->get();


 さらに、orderByRaw関数であれば第2引数に配列を指定することでバインドしてくれるということが分かったので、なおさらDB::raw関数を使う意味がなくなりました。

 例えば、下記のような感じでコーディングすればLaravel側がバインドしてくれるので、エスケープ作業をする必要がなくなります


$ids = array(1,3,5,7,9);

$placeholder = '';
foreach ($ids as $key => $value) {
   $placeholder .= ($key == 0) ? '?' : ',?';
}
                    
$data = Data::whereIn('id', $ids)->orderByRaw("FIELD(id, $placeholder)",$ids)->get();


 これが一番まともなコーディングかもしれません。

 しかし、Laravelやっぱり便利だな。

 ということで、以上、今回はここまで!Takaでした。また!

この記事のまとめ

  • EloquentでwhereInを使った場合に配列の並び順にソートする方法

お仕事のご相談・ご依頼
お気軽にお問い合わせください!

お仕事の依頼はこちら

著者プロフィール

Taka

東京、奄美大島を拠点にサーフィンとスノーボードが好きなフリーランスのWebクリエイターです。普段はプログラム書いたりデザインしたり映像作ったりしています。いろいろな人の話しを聞くのが好きなので、このブログを通して多くの人と繋がりが出来たら嬉しいです。noteとInstagramもやっているのでフォローしてくれたらありがたいです!

人気記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です